X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fdevtools%2Fexprefs.c;fp=src%2Fdevtools%2Fexprefs.c;h=cfd394100eec9c21dd7d5f940637359f64184267;hb=40b7650e4c95481889c1e37dea57be7de018e37d;hp=4459f2c4b5e5f5f811bf546547f16ca3eb13743e;hpb=9a623c3aa32ec0fbf9682f37a990abd00f38da60;p=src%2Fapp-framework-binder.git diff --git a/src/devtools/exprefs.c b/src/devtools/exprefs.c index 4459f2c4..cfd39410 100644 --- a/src/devtools/exprefs.c +++ b/src/devtools/exprefs.c @@ -43,105 +43,91 @@ #define _GNU_SOURCE #include #include -#include #include +#include "getref.h" +#include "exprefs.h" + /** * records path to the expanded node */ struct path { struct json_object *object; /**< node being expanded */ - struct path *upper; /**< link to upper expanded nodes */ + const struct path *upper; /**< link to upper expanded nodes */ }; /** - * root of the JSON being parsed - */ -struct json_object *root; - -/** - * Search for a reference of type "#/a/b/c" int the - * parsed JSON object + * Returns the top object */ -struct json_object *search(const char *path) +static inline struct json_object *top(const struct path *path) { - char *d; - struct json_object *i; - - /* does it match #/ at the beginning? */ - if (path[0] != '#' || (path[0] && path[1] != '/')) - return NULL; - - /* search from root to target */ - i = root; - d = strdupa(path+2); - d = strtok(d, "/"); - while(i && d) { - if (!json_object_object_get_ex(i, d, &i)) - return NULL; - d = strtok(NULL, "/"); - } - return i; + while (path->upper) + path = path->upper; + return path->object; } /** * Expands the node designated by path and returns its expanded form */ -struct json_object *expand(struct path path) +static struct json_object *expand(const struct path *upper) { - struct path *p; - struct json_object *o, *x; + struct path here; + struct json_object *object, *x; int n, i; struct json_object_iterator ji, jn; /* expansion depends of the type of the node */ - switch (json_object_get_type(path.object)) { + here.upper = upper; + object = upper->object; + switch (json_object_get_type(object)) { case json_type_object: /* for object, look if it contains a property "$ref" */ - if (json_object_object_get_ex(path.object, "$ref", &o)) { - /* yes, reference, try to substitute its target */ - if (!json_object_is_type(o, json_type_string)) { - fprintf(stderr, "found a $ref not being string. Is: %s\n", json_object_get_string(o)); + if (json_object_object_get_ex(object, "$ref", &here.object)) { + /* check that "$ref" value is a string */ + if (!json_object_is_type(here.object, json_type_string)) { + fprintf(stderr, "found a $ref not being string. Is: %s\n", json_object_get_string(here.object)); exit(1); } - x = search(json_object_get_string(o)); - if (!x) { - fprintf(stderr, "$ref not found. Was: %s\n", json_object_get_string(o)); + /* yes, reference, try to substitute its target */ + i = search$ref(top(upper), json_object_get_string(here.object), &x); + if (!i) { + fprintf(stderr, "$ref not found. Was: %s\n", json_object_get_string(here.object)); exit(1); } - p = &path; - while(p) { - if (x == p->object) { - fprintf(stderr, "$ref recursive. Was: %s\n", json_object_get_string(o)); + /* check not recursive */ + upper = &here; + while(upper) { + if (x == upper->object) { + fprintf(stderr, "$ref recursive. Was: %s\n", json_object_get_string(here.object)); exit(1); } - p = p->upper; + upper = upper->upper; } - /* cool found, return a new instance of the target */ - return json_object_get(x); + /* found. return a new instance of the target */ + return x; } /* no, expand the values */ - ji = json_object_iter_begin(path.object); - jn = json_object_iter_end(path.object); + ji = json_object_iter_begin(object); + jn = json_object_iter_end(object); while (!json_object_iter_equal(&ji, &jn)) { - o = json_object_iter_peek_value(&ji); - x = expand((struct path){ .object = o, .upper = &path }); - if (x != o) - json_object_object_add(path.object, json_object_iter_peek_name(&ji), x); + here.object = json_object_iter_peek_value(&ji); + x = expand(&here); + if (x != here.object) + json_object_object_add(object, json_object_iter_peek_name(&ji), json_object_get(x)); json_object_iter_next(&ji); } break; case json_type_array: /* expand the values of arrays */ i = 0; - n = (int)json_object_array_length(path.object); + n = (int)json_object_array_length(object); while (i != n) { - o = json_object_array_get_idx(path.object, i); - x = expand((struct path){ .object = o, .upper = &path }); - if (x != o) - json_object_array_put_idx(path.object, i, x); + here.object = json_object_array_get_idx(object, i); + x = expand(&here); + if (x != here.object) + json_object_array_put_idx(object, i, json_object_get(x)); i++; } break; @@ -150,49 +136,62 @@ struct json_object *expand(struct path path) break; } /* return the given node */ - return path.object; + return object; } -/** - * process a file and prints its expansion on stdout - */ -void process(char *filename) +struct json_object *exp$refs(struct json_object *root) { - /* translate - */ - if (!strcmp(filename, "-")) - filename = "/dev/stdin"; + struct path top = { .object = root, .upper = NULL }; + return expand(&top); +} - /* check access */ - if (access(filename, R_OK)) { - fprintf(stderr, "can't access file %s\n", filename); - exit(1); - } +static int is_tree(struct json_object *object, const struct path *upper) +{ + struct path here; + int n, i; + struct json_object_iterator ji, jn; - /* read the file */ - root = json_object_from_file(filename); - if (!root) { - fprintf(stderr, "reading file %s produced null\n", filename); - exit(1); + switch (json_object_get_type(object)) { + case json_type_object: + case json_type_array: + /* check recursive */ + here.upper = upper; + while (upper) { + if (upper->object == object) + return 0; + upper = upper->upper; + } + here.object = object; + switch (json_object_get_type(object)) { + case json_type_object: + ji = json_object_iter_begin(object); + jn = json_object_iter_end(object); + while (!json_object_iter_equal(&ji, &jn)) { + if (!is_tree(json_object_iter_peek_value(&ji), &here)) + return 0; + json_object_iter_next(&ji); + } + break; + case json_type_array: + i = 0; + n = (int)json_object_array_length(object); + while (i != n) { + if (!is_tree(json_object_array_get_idx(object, i), &here)) + return 0; + i++; + } + break; + default: + break; + } + break; + default: + break; } - - /* expand */ - root = expand((struct path){ .object = root, .upper = NULL }); - - /* print the result */ - json_object_to_file_ext ("/dev/stdout", root, JSON_C_TO_STRING_PRETTY); - - /* clean up */ - json_object_put(root); + return 1; } -/** process the list of files or stdin if none */ -int main(int ac, char **av) +int exp$refs_is_tree(struct json_object *root) { - if (!*++av) - process("-"); - else { - do { process(*av); } while(*++av); - } - return 0; + return is_tree(root, NULL); } -