From: Heng Li Date: Sun, 30 Nov 2014 00:40:08 +0000 (-0500) Subject: query on CMD; more chanages to happen X-Git-Url: http://www.kaiwu.me/postgresql/commit/static/gitweb.js?a=commitdiff_plain;h=c81aca32bf99bd787b823b3e5471a6ebe1924854;p=klib.git query on CMD; more chanages to happen --- diff --git a/kson.c b/kson.c index 9546853..204ecac 100644 --- a/kson.c +++ b/kson.c @@ -5,6 +5,10 @@ #include #include "kson.h" +/************* + *** Parse *** + *************/ + kson_node_t *kson_parse_core(const char *json, long *_n, int *error, long *parsed_len) { long *stack = 0, top = 0, max = 0, n_a = 0, m_a = 0; @@ -79,7 +83,7 @@ kson_node_t *kson_parse_core(const char *json, long *_n, int *error, long *parse for (q = ++p; *q && *q != c; ++q) if (*q == '\\') ++q; } else { - for (q = p; *q && *q != ']' && *q != '}' && *q != ',' && *q != ':'; ++q) + for (q = p; *q && *q != ']' && *q != '}' && *q != ',' && *q != ':' && *q != '\n'; ++q) if (*q == '\\') ++q; } u->v.str = (char*)malloc(q - p + 1); strncpy(u->v.str, p, q - p); u->v.str[q-p] = 0; // equivalent to u->v.str=strndup(p, q-p) @@ -98,13 +102,12 @@ kson_node_t *kson_parse_core(const char *json, long *_n, int *error, long *parse void kson_destroy(kson_t *kson) { - if (kson) { - long i; - for (i = 0; i < kson->n_nodes; ++i) { - free(kson->nodes[i].key); free(kson->nodes[i].v.str); - } - free(kson->nodes); free(kson); + long i; + if (kson == 0) return; + for (i = 0; i < kson->n_nodes; ++i) { + free(kson->nodes[i].key); free(kson->nodes[i].v.str); } + free(kson->nodes); free(kson); } kson_t *kson_parse(const char *json, int *error) @@ -119,40 +122,31 @@ kson_t *kson_parse(const char *json, int *error) return kson; } -const kson_node_t *kson_vquery(const kson_node_t *nodes, const kson_node_t *root, int depth, va_list ap) +/************* + *** Query *** + *************/ + +const kson_node_t *kson_query(const kson_t *kson, int depth, ...) { - const kson_node_t *p = root; + const kson_node_t *p = kson->nodes; + va_list ap; + va_start(ap, depth); 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; + p = kson_by_key(kson->nodes, p, va_arg(ap, const char*)); } else if (p->type == KSON_TYPE_BRACKET) { - long i = va_arg(ap, long); - p = i < (long)p->n? &nodes[p->v.child[i]] : 0; + p = kson_by_index(kson->nodes, p, va_arg(ap, long)); } 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; } +/************** + *** Fromat *** + **************/ + void kson_format_recur(const kson_node_t *nodes, int depth, const kson_node_t *p) { long i; @@ -162,9 +156,8 @@ void kson_format_recur(const kson_node_t *nodes, int depth, const kson_node_t *p } if (p->type == KSON_TYPE_BRACKET || p->type == KSON_TYPE_BRACE) { putchar(p->type == KSON_TYPE_BRACKET? '[' : '{'); - putchar('\n'); if (p->n) { - for (i = 0; i <= depth; ++i) fputs(" ", stdout); + putchar('\n'); for (i = 0; i <= depth; ++i) fputs(" ", stdout); for (i = 0; i < (long)p->n; ++i) { if (i) { int i; @@ -173,9 +166,8 @@ void kson_format_recur(const kson_node_t *nodes, int depth, const kson_node_t *p } kson_format_recur(nodes, depth + 1, &nodes[p->v.child[i]]); } - putchar('\n'); + putchar('\n'); for (i = 0; i < depth; ++i) fputs(" ", stdout); } - for (i = 0; i < depth; ++i) fputs(" ", stdout); putchar(p->type == KSON_TYPE_BRACKET? ']' : '}'); } else { if (p->type != KSON_TYPE_NO_QUOTE) @@ -192,6 +184,10 @@ void kson_format(const kson_t *kson) putchar('\n'); } +/********************* + *** Main function *** + *********************/ + #ifdef KSON_MAIN #define kroundup32(x) (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x)) int main(int argc, char *argv[]) @@ -200,9 +196,10 @@ int main(int argc, char *argv[]) int error; if (argc > 1) { FILE *fp; - int len = 0, max = 0, tmp; + int len = 0, max = 0, tmp, i; char *json = 0, buf[0x10000]; if ((fp = fopen(argv[1], "rb")) != 0) { + // read the entire file into a string while ((tmp = fread(buf, 1, 0x10000, fp)) != 0) { if (len + tmp + 1 > max) { max = len + tmp + 1; @@ -213,9 +210,27 @@ int main(int argc, char *argv[]) len += tmp; } fclose(fp); + // parse kson = kson_parse(json, &error); - if (kson) kson_format(kson); - else printf("Error code: %d\n", error); + free(json); + if (kson) { + kson_format(kson); + if (argc > 2) { + // path finding + const kson_node_t *p = kson->nodes; + for (i = 2; i < argc && p; ++i) { + if (p->type == KSON_TYPE_BRACKET) + p = kson_by_index(kson->nodes, p, atoi(argv[i])); + else if (p->type == KSON_TYPE_BRACE) + p = kson_by_key(kson->nodes, p, argv[i]); + else p = 0; + } + if (p) { + if (kson_is_internal(p)) printf("Reached an internal node\n"); + else printf("Value: %s\n", p->v.str); + } else printf("Failed to find the slot\n"); + } + } else printf("Error code: %d\n", error); } } else { kson = kson_parse("{'a' : 1,'b':[0,'isn\\'t',true],'d':[{\n}]}", &error); diff --git a/kson.h b/kson.h index e9f1f27..25845ad 100644 --- a/kson.h +++ b/kson.h @@ -55,4 +55,20 @@ extern "C" { } #endif +static inline const kson_node_t *kson_by_key(const kson_node_t *nodes, const kson_node_t *p, const char *key) +{ + long i; + for (i = 0; i < (long)p->n; ++i) { + const kson_node_t *q = &nodes[p->v.child[i]]; + if (q->key && strcmp(q->key, key) == 0) + return q; + } + return 0; +} + +static inline const kson_node_t *kson_by_index(const kson_node_t *nodes, const kson_node_t *p, long i) +{ + return 0 <= i && i < (long)p->n? &nodes[p->v.child[i]] : 0; +} + #endif