jsonpath *parse(parser_context *context) { PRECOND_NONNULL_ELSE_NULL(context); PRECOND_NONNULL_ELSE_NULL(context->path); PRECOND_NONNULL_ELSE_NULL(context->input); PRECOND_ELSE_NULL(0 != context->length); debug_string("parsing expression: '%s'", context->input, context->length); if(parse_expression(context)) { parser_debug("done. found %zd steps.", context->path->length); return context->path; } else { context->result.actual_char = context->input[context->cursor]; #ifdef USE_LOGGING char *message = parser_status_message(context); parser_error("aborted. unable to create jsonpath model. status: %d (%s)", context->result.code, message); free(message); #endif path_free(context->path); context->path = NULL; return NULL; } }
step *path_get(const jsonpath *path, size_t index) { PRECOND_NONNULL_ELSE_NULL(path); PRECOND_NONNULL_ELSE_NULL(path->steps); PRECOND_ELSE_NULL(0 != path->length, index < path->length); return path->steps[index]; }
char *loader_status_message(const struct loader_context *context) { PRECOND_NONNULL_ELSE_NULL(context); char *message = NULL; int result = 0; switch (context->code) { case ERR_READER_FAILED: result = asprintf(&message, MESSAGES[context->code], context->parser.problem, context->parser.problem_offset); break; case ERR_PARSER_FAILED: case ERR_SCANNER_FAILED: result = asprintf(&message, MESSAGES[context->code], context->parser.problem, context->parser.problem_mark.line+1, context->parser.problem_mark.column+1); break; case ERR_ALIAS_LOOP: case ERR_NO_ANCHOR_FOR_ALIAS: case ERR_NON_SCALAR_KEY: case ERR_DUPLICATE_KEY: result = asprintf(&message, MESSAGES[context->code], context->parser.mark.line); break; default: message = strdup(MESSAGES[context->code]); break; } if(-1 == result) { message = NULL; } return message; }
node *document_root(const node *document) { PRECOND_NONNULL_ELSE_NULL(document); PRECOND_ELSE_NULL(DOCUMENT == node_kind(document)); return document->content.target; }
node *model_document(const document_model *model, size_t index) { PRECOND_NONNULL_ELSE_NULL(model); PRECOND_ELSE_NULL(index < model_document_count(model)); return vector_get(model->documents, index); }
node *alias_target(const node *alias) { PRECOND_NONNULL_ELSE_NULL(alias); PRECOND_ELSE_NULL(ALIAS == node_kind(alias)); return alias->content.target; }
uint8_t *scalar_value(const node *scalar) { PRECOND_NONNULL_ELSE_NULL(scalar); PRECOND_ELSE_NULL(SCALAR == node_kind(scalar)); return scalar->content.scalar.value; }
node *sequence_get(const node *sequence, size_t index) { PRECOND_NONNULL_ELSE_NULL(sequence); PRECOND_ELSE_NULL(SEQUENCE == node_kind(sequence)); PRECOND_ELSE_NULL(index < node_size(sequence)); return vector_get(sequence->content.sequence, index); }
bool sequence_iterate(const node *sequence, sequence_iterator iterator, void *context) { PRECOND_NONNULL_ELSE_FALSE(sequence, iterator); PRECOND_ELSE_FALSE(SEQUENCE == node_kind(sequence)); context_adapter adapter = {.iterator.sequence=iterator, .context=context }; return vector_iterate(sequence->content.sequence, sequence_iterator_adpater, &adapter); } node *mapping_get(const node *mapping, uint8_t *scalar, size_t length) { PRECOND_NONNULL_ELSE_NULL(mapping, scalar); PRECOND_ELSE_NULL(MAPPING == node_kind(mapping)); PRECOND_ELSE_NULL(0 < length); node *key = make_scalar_node(scalar, length, SCALAR_STRING); node *result = hashtable_get(mapping->content.mapping, key); node_free(key); return result; }
predicate *step_predicate(const step *value) { PRECOND_NONNULL_ELSE_NULL(value); PRECOND_NONNULL_ELSE_NULL(value->predicate); return value->predicate; }
uint8_t *name_test_step_name(const step *value) { PRECOND_NONNULL_ELSE_NULL(value); PRECOND_ELSE_NULL(NAME_TEST == value->test.kind); return value->test.name.value; }
uint8_t *path_expression(const jsonpath *path) { PRECOND_NONNULL_ELSE_NULL(path); return path->expression; }
node *node_parent(const node *value) { PRECOND_NONNULL_ELSE_NULL(value); return value->parent; }
uint8_t *node_name(const node *value) { PRECOND_NONNULL_ELSE_NULL(value); return value->tag.name; }