aboutsummaryrefslogtreecommitdiffstats
path: root/src/devtools/exprefs.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/devtools/exprefs.c')
-rw-r--r--src/devtools/exprefs.c183
1 files changed, 91 insertions, 92 deletions
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 <string.h>
#include <stdio.h>
-#include <unistd.h>
#include <json-c/json.h>
+#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);
}
-