#include <string.h>
#include <stdlib.h>
+#include <stdarg.h>
#include <ctype.h>
#include <stdio.h>
#include "kson.h"
return kson;
}
-void kson_print_recur(kson_node_t *nodes, kson_node_t *p)
+void kson_print_recur(const kson_node_t *nodes, const kson_node_t *p)
{
if (p->key) {
printf("\"%s\"", p->key);
}
}
-void kson_print(kson_t *kson)
+void kson_print(const kson_t *kson)
{
kson_print_recur(kson->nodes, kson->nodes);
}
+const kson_node_t *kson_vquery(const kson_node_t *nodes, const kson_node_t *root, int depth, va_list ap)
+{
+ const kson_node_t *p = root;
+ while (p && depth > 0) {
+ if (p->type == KSON_TYPE_BRACE) {
+ long i;
+ const char *q = va_arg(ap, const char*);
+ for (i = 0; i < (long)p->n; ++i) {
+ const kson_node_t *r = &nodes[i];
+ if (r->key && strcmp(r->key, q) == 0) {
+ p = r;
+ break;
+ }
+ }
+ if (i == (long)p->n) p = 0;
+ } else if (p->type == KSON_TYPE_BRACKET) {
+ long i = va_arg(ap, long);
+ p = i < (long)p->n? &nodes[p->v.child[i]] : 0;
+ } else break;
+ --depth;
+ }
+ return p;
+}
+
+const kson_node_t *kson_query(const kson_t *kson, int depth, ...)
+{
+ const kson_node_t *p;
+ va_list ap;
+ va_start(ap, depth);
+ p = kson_vquery(kson->nodes, kson->nodes, depth, ap);
+ va_end(ap);
+ return p;
+}
+
#ifdef KSON_MAIN
int main(int argc, char *argv[])
{
int error;
kson = kson_parse("{'a' : 1, 'b':[0,'isn\\'t',true],'d':[{\n}]}", &error);
if (error == 0) {
+ const kson_node_t *p = kson_query(kson, 2, "b", 1);
+ printf("*** %s\n", p->v.str);
kson_print(kson);
putchar('\n');
} else {
kson_node_t *nodes;
} kson_t;
+#define kson_is_internal(p) ((p)->type == KSON_TYPE_BRACKET || (p)->type == KSON_TYPE_BRACE)
+
#ifdef __cplusplus
extern "C" {
#endif
/**
- * Parse a JSON string into nodes
+ * Parse a JSON string
*
- * @param json JSON string
- * @param n_nodes number of nodes
- * @param error 0 if no error; or set to one of KSON_ERR_* values
- * @param parsed_len if not NULL, equal to the parsed length
+ * @param json JSON string
+ * @param error error code
*
- * @return An array of size $n_nodes keeping parsed nodes
+ * @return a pointer to kson_t if *error==0; or NULL otherwise
*/
- kson_node_t *kson_parse_core(const char *json, long *n_nodes, int *error, long *parsed_len);
-
- // Equivalent to: { kson->nodes = kson_parse_core(json, &kson->n_nodes, &error, 0); return *error? 0 : kson; }
kson_t *kson_parse(const char *json, int *error);
+ /** Destroy a kson_t object */
void kson_destroy(kson_t *kson);
- void kson_print(kson_t *kson);
+
+ const kson_node_t *kson_query(const kson_t *kson, int max_depth, ...);
+
+ void kson_print(const kson_t *kson);
+ kson_node_t *kson_parse_core(const char *json, long *n_nodes, int *error, long *parsed_len);
#ifdef __cplusplus
}