X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fdevtools%2Fmain-genskel.c;fp=src%2Fdevtools%2Fgenskel.c;h=bad7ee9748ed79899ee128a2362718d7a5af25a2;hb=40b7650e4c95481889c1e37dea57be7de018e37d;hp=80dcd3818cf06d271cfb3f88841d358938c26c97;hpb=9a623c3aa32ec0fbf9682f37a990abd00f38da60;p=src%2Fapp-framework-binder.git diff --git a/src/devtools/genskel.c b/src/devtools/main-genskel.c similarity index 70% rename from src/devtools/genskel.c rename to src/devtools/main-genskel.c index 80dcd381..bad7ee97 100644 --- a/src/devtools/genskel.c +++ b/src/devtools/main-genskel.c @@ -14,31 +14,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -/* - * This simple program expands the object { "$ref": "#/path/to/a/target" } - * - * For example: - * - * { - * "type":{ - * "a": "int", - * "b": { "$ref": "#/type/a" } - * } - * } - * - * will be exapanded to - * - * { - * "type":{ - * "a": "int", - * "b": "int" - * } - * } - * - * Invocation: program [file|-]... - * - * without arguments, it reads the input. - */ #define _GNU_SOURCE #include @@ -48,17 +23,12 @@ #include -#define T(x) ((x) && *(x)) -#define oom(x) do{if(!(x)){fprintf(stderr,"out of memory\n");exit(1);}}while(0) +#include "getref.h" +#include "exprefs.h" +#include "json2c.h" -/** - * records path to the expanded node - */ -struct path -{ - struct json_object *object; /**< node being expanded */ - struct path *upper; /**< link to upper expanded nodes */ -}; +#define TEST(x) ((x) && *(x)) +#define OOM(x) do{if(!(x)){fprintf(stderr,"out of memory\n");exit(1);}}while(0) /** * root of the JSON being parsed @@ -77,103 +47,17 @@ const char *postfix = NULL; const char *provideclass = NULL; const char *requireclass = NULL; const char *requireapi = NULL; +const char *info = NULL; char *capi = NULL; int priv = -1; int noconc = -1; int cpp = 0; +enum idl { + idl_afbidl = 0, + idl_openapi = 1 +} idl = idl_openapi; -/** - * Search for a reference of type "#/a/b/c" in the - * parsed JSON object (root) - */ -struct json_object *search(const char *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; -} - -/** - * Expands the node designated by path and returns its expanded form - */ -struct json_object *expand_$ref(struct path path) -{ - struct path *p; - struct json_object *o, *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)) { - 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)); - exit(1); - } - x = search(json_object_get_string(o)); - if (!x) { - fprintf(stderr, "$ref not found. Was: %s\n", json_object_get_string(o)); - exit(1); - } - p = &path; - while(p) { - if (x == p->object) { - fprintf(stderr, "$ref recursive. Was: %s\n", json_object_get_string(o)); - exit(1); - } - p = p->upper; - } - /* cool found, return a new instance of the target */ - return json_object_get(x); - } - /* no, expand the values */ - ji = json_object_iter_begin(path.object); - jn = json_object_iter_end(path.object); - while (!json_object_iter_equal(&ji, &jn)) { - o = json_object_iter_peek_value(&ji); - x = expand_$ref((struct path){ .object = o, .upper = &path }); - if (x != o) - json_object_object_add(path.object, json_object_iter_peek_name(&ji), 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); - while (i != n) { - o = json_object_array_get_idx(path.object, i); - x = expand_$ref((struct path){ .object = o, .upper = &path }); - if (x != o) - json_object_array_put_idx(path.object, i, x); - i++; - } - break; - default: - /* otherwise no expansion */ - break; - } - /* return the given node */ - return path.object; -} /* create c name by replacing non alpha numeric characters with underscores */ char *cify(const char *str) @@ -188,97 +72,14 @@ char *cify(const char *str) return r; } -/* format the specification as a C string */ -char *make_info(const char *text, int split) -{ - const char *a, *b; - char *desc, c, buf[3] = {0}; - size_t len; - int i, pos, e; - - /* estimated length */ - a = b = text; - len = 1; - while((c = *b++)) { - len += 1 + ('"' == c); - } - - len += 7 * (1 + len / 72); - desc = malloc(len); - oom(desc); - - len = pos = 0; - if (!split) - desc[len++] = '"'; - b = a; - while((c = *b++)) { - if (c == '"') { - buf[0] = '\\'; - buf[1] = '"'; - buf[2] = 0; - } - else if (c == '\\') { - switch ((c = *b++)) { - case 0: - b--; - buf[0] = 0; - break; - case '/': - buf[0] = '/'; - buf[1] = 0; - break; - default: - buf[0] = '\\'; - buf[1] = c; - buf[2] = 0; - break; - } - } - else { - buf[0] = c; - buf[1] = 0; - } - i = e = 0; - while (buf[i]) { - if (split) { - if (pos >= 77 && !e) { - desc[len++] = '"'; - desc[len++] = '\n'; - pos = 0; - } - if (pos == 0) { - desc[len++] = ' '; - desc[len++] = ' '; - desc[len++] = ' '; - desc[len++] = ' '; - desc[len++] = '"'; - pos = 5; - } - } - c = buf[i++]; - desc[len++] = c; - e = !e && c == '\\'; - pos++; - } - } - desc[len++] = '"'; - if (split) - desc[len++] = '\n'; - desc[len] = 0; - return desc; -} - -/* make the description of the object */ -char *make_desc(struct json_object *o) -{ - return make_info(json_object_to_json_string_ext(o, 0), 1); -} - /* get the permission odescription if set */ struct json_object *permissions_of_verb(struct json_object *obj) { struct json_object *x, *y; + if (idl == idl_afbidl) + return json_object_object_get_ex(obj, "permissions", &x) ? x : NULL; + if (json_object_object_get_ex(obj, "x-permissions", &x)) return x; @@ -540,7 +341,7 @@ void print_verb(const char *name) void print_declare_verb(const char *name, struct json_object *obj) { - if (T(scope)) + if (TEST(scope)) printf("%s ", scope); printf("void "); print_verb(name); @@ -569,7 +370,7 @@ void print_struct_verb(const char *name, struct json_object *obj) " .auth = %s,\n" " .info = %s,\n" , p && decl_perm(p) ? json_object_get_string(decl_perm(p)) : "NULL" - , info ? make_info(info, 0) : "NULL" + , info ? str2c_inl(info) : "NULL" ); if (version == 3) printf( @@ -590,14 +391,60 @@ void print_struct_verb(const char *name, struct json_object *obj) ); } -void enum_verbs(void (*func)(const char *name, struct json_object *obj)) +void getvarbool(int *var, const char *path, int defval) +{ + struct json_object *o; + + if (*var != 0 && *var != 1) { + o = get$ref(root, path); + if (o && json_object_is_type(o, json_type_boolean)) + *var = json_object_get_boolean(o); + else + *var = !!defval; + } +} + +void getvar(const char **var, const char *path, const char *defval) +{ + struct json_object *o; + + if (!*var) { + o = get$ref(root, path); + if (o && json_object_is_type(o, json_type_string)) + *var = json_object_get_string(o); + else + *var = defval; + } +} + +/******************************************************************************/ + +void openapi_getvars() +{ + getvar(&api, "#/info/x-binding-c-generator/api", NULL); + getvar(&preinit, "#/info/x-binding-c-generator/preinit", NULL); + getvar(&init, "#/info/x-binding-c-generator/init", NULL); + getvar(&onevent, "#/info/x-binding-c-generator/onevent", NULL); + getvar(&scope, "#/info/x-binding-c-generator/scope", "static"); + getvar(&prefix, "#/info/x-binding-c-generator/prefix", "afb_verb_"); + getvar(&postfix, "#/info/x-binding-c-generator/postfix", "_cb"); + getvar(&provideclass, "#/info/x-binding-c-generator/provide-class", NULL); + getvar(&requireclass, "#/info/x-binding-c-generator/require-class", NULL); + getvar(&requireapi, "#/info/x-binding-c-generator/require-api", NULL); + getvarbool(&priv, "#/info/x-binding-c-generator/private", 0); + getvarbool(&noconc, "#/info/x-binding-c-generator/noconcurrency", 0); + getvar(&api, "#/info/title", "?"); + getvar(&info, "#/info/description", NULL); +} + +void openapi_enum_verbs(void (*func)(const char *name, struct json_object *obj)) { struct json_object_iterator ji, jn; struct json_object *paths, *obj; const char *name; /* search the verbs */ - paths = search("#/paths"); + paths = get$ref(root, "#/paths"); if (!paths) return; @@ -613,29 +460,63 @@ void enum_verbs(void (*func)(const char *name, struct json_object *obj)) } } -void getvarbool(int *var, const char *path, int defval) +/******************************************************************************/ + +void afbidl_getvars() { - struct json_object *o; + getvar(&preinit, "#/generator/genskel/preinit", NULL); + getvar(&init, "#/generator/genskel/init", NULL); + getvar(&onevent, "#/generator/genskel/onevent", NULL); + getvar(&scope, "#/generator/genskel/scope", "static"); + getvar(&prefix, "#/generator/genskel/prefix", "afb_verb_"); + getvar(&postfix, "#/generator/genskel/postfix", "_cb"); + getvar(&provideclass, "#/generator/genskel/provide-class", NULL); + getvar(&requireclass, "#/generator/genskel/require-class", NULL); + getvar(&requireapi, "#/generator/genskel/require-api", NULL); + getvarbool(&priv, "#/generator/genskel/private", 0); + getvarbool(&noconc, "#/generator/genskel/noconcurrency", 0); + getvar(&api, "#/api/name", NULL); + getvar(&api, "#/info/title", "?"); + getvar(&info, "#/info/description", NULL); +} - if (*var != 0 && *var != 1) { - o = search(path); - if (o && json_object_is_type(o, json_type_boolean)) - *var = json_object_get_boolean(o); - else - *var = !!defval; +void afbidl_enum_verbs(void (*func)(const char *name, struct json_object *obj)) +{ + struct json_object_iterator ji, jn; + struct json_object *verbs, *obj; + const char *name; + + /* search the verbs */ + verbs = get$ref(root, "#/api/verbs"); + if (!verbs) + return; + + /* list the verbs and sort it */ + ji = json_object_iter_begin(verbs); + jn = json_object_iter_end(verbs); + while (!json_object_iter_equal(&ji, &jn)) { + name = json_object_iter_peek_name(&ji); + obj = json_object_iter_peek_value(&ji); + func(name, obj); + json_object_iter_next(&ji); } } -void getvar(const char **var, const char *path, const char *defval) +/******************************************************************************/ + +void detectidl() { struct json_object *o; - if (!*var) { - o = search(path); - if (o && json_object_is_type(o, json_type_string)) - *var = json_object_get_string(o); - else - *var = defval; + o = get$ref(root, "#/openapi"); + if (o) { + idl = idl_openapi; + return; + } + o = get$ref(root, "#/afbidl"); + if (o) { + idl = idl_afbidl; + return; } } @@ -645,7 +526,9 @@ void getvar(const char **var, const char *path, const char *defval) void process(char *filename) { char *desc; - const char *info; + + void (*getvars)(); + void (*enum_verbs)(void (*)(const char*, struct json_object*)); /* translate - */ if (!strcmp(filename, "-")) @@ -664,28 +547,28 @@ void process(char *filename) exit(1); } - /* create the description */ - desc = make_desc(root); + /* create the description (before expanding $ref ) */ + desc = json2c_std(root); /* expand references */ - root = expand_$ref((struct path){ .object = root, .upper = NULL }); + root = exp$refs(root); + + /* detect the idl */ + detectidl(); + switch(idl) { + default: + case idl_afbidl: + getvars = afbidl_getvars; + enum_verbs = afbidl_enum_verbs; + break; + case idl_openapi: + getvars = openapi_getvars; + enum_verbs = openapi_enum_verbs; + break; + } /* get some names */ - getvar(&api, "#/info/x-binding-c-generator/api", NULL); - getvar(&preinit, "#/info/x-binding-c-generator/preinit", NULL); - getvar(&init, "#/info/x-binding-c-generator/init", NULL); - getvar(&onevent, "#/info/x-binding-c-generator/onevent", NULL); - getvar(&scope, "#/info/x-binding-c-generator/scope", "static"); - getvar(&prefix, "#/info/x-binding-c-generator/prefix", "afb_verb_"); - getvar(&postfix, "#/info/x-binding-c-generator/postfix", "_cb"); - getvar(&provideclass, "#/info/x-binding-c-generator/provide-class", NULL); - getvar(&requireclass, "#/info/x-binding-c-generator/require-class", NULL); - getvar(&requireapi, "#/info/x-binding-c-generator/require-api", NULL); - getvarbool(&priv, "#/info/x-binding-c-generator/private", 0); - getvarbool(&noconc, "#/info/x-binding-c-generator/noconcurrency", 0); - getvar(&api, "#/info/title", "?"); - info = NULL; - getvar(&info, "#/info/description", NULL); + getvars(); capi = cify(api); /* get the API name */ @@ -727,22 +610,22 @@ void process(char *filename) ); printf( "\n" - " }\n" + " }\n" "};\n" ); - if (T(preinit) || T(init) || T(onevent)) { + if (TEST(preinit) || TEST(init) || TEST(onevent)) { printf("\n"); - if (T(preinit)) { - if (T(scope)) printf("%s ", scope); + if (TEST(preinit)) { + if (TEST(scope)) printf("%s ", scope); printf("int %s(%s);\n", preinit, version==3 ? "afb_api_t api" : ""); } - if (T(init)) { - if (T(scope)) printf("%s ", scope); + if (TEST(init)) { + if (TEST(scope)) printf("%s ", scope); printf("int %s(%s);\n", init, version==3 ? "afb_api_t api" : ""); } - if (T(onevent)) { - if (T(scope)) printf("%s ", scope); + if (TEST(onevent)) { + if (TEST(scope)) printf("%s ", scope); printf("void %s(%sconst char *event, struct json_object *object);\n", onevent, version==3 ? "afb_api_t api, " : ""); } @@ -764,11 +647,11 @@ void process(char *filename) , priv ? capi : "" , api , capi - , info ? make_info(info, 0) : "NULL" + , info ? str2c_inl(info) : "NULL" , capi - , T(preinit) ? preinit : "NULL" - , T(init) ? init : "NULL" - , T(onevent) ? onevent : "NULL" + , TEST(preinit) ? preinit : "NULL" + , TEST(init) ? init : "NULL" + , TEST(onevent) ? onevent : "NULL" ); @@ -778,9 +661,9 @@ void process(char *filename) " .provide_class = %s%s%s,\n" " .require_class = %s%s%s,\n" " .require_api = %s%s%s,\n" - , T(provideclass) ? "\"" : "", T(provideclass) ? provideclass : "NULL", T(provideclass) ? "\"" : "" - , T(requireclass) ? "\"" : "", T(requireclass) ? requireclass : "NULL", T(requireclass) ? "\"" : "" - , T(requireapi) ? "\"" : "", T(requireapi) ? requireapi : "NULL", T(requireapi) ? "\"" : "" + , TEST(provideclass) ? "\"" : "", TEST(provideclass) ? provideclass : "NULL", TEST(provideclass) ? "\"" : "" + , TEST(requireclass) ? "\"" : "", TEST(requireclass) ? requireclass : "NULL", TEST(requireclass) ? "\"" : "" + , TEST(requireapi) ? "\"" : "", TEST(requireapi) ? requireapi : "NULL", TEST(requireapi) ? "\"" : "" );