X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fdevtools%2Fgenskel.c;h=aab2e5608cf3bb259da48eff94cda6cd7e36b96a;hb=65353dce81a629e042800bb7b86fcd869a76727e;hp=c021fdfc96a3174057754c1bc801cd7314b0ae47;hpb=a1069bceb51ca4472d121eb205f2a3082e5dcda3;p=src%2Fapp-framework-binder.git diff --git a/src/devtools/genskel.c b/src/devtools/genskel.c index c021fdfc..aab2e560 100644 --- a/src/devtools/genskel.c +++ b/src/devtools/genskel.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016, 2017 "IoT.bzh" + * Copyright (C) 2015-2020 "IoT.bzh" * Author José Bollo * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -48,6 +48,7 @@ #include +#define T(x) ((x) && *(x)) #define oom(x) do{if(!(x)){fprintf(stderr,"out of memory\n");exit(1);}}while(0) /** @@ -62,6 +63,7 @@ struct path /** * root of the JSON being parsed */ +int version = 3; struct json_object *root = NULL; struct json_object *d_perms = NULL; struct json_object *a_perms = NULL; @@ -72,14 +74,17 @@ const char *api = NULL; const char *scope = NULL; const char *prefix = NULL; const char *postfix = NULL; +const char *provideclass = NULL; +const char *requireclass = NULL; +const char *requireapi = NULL; char *capi = NULL; int priv = -1; int noconc = -1; int cpp = 0; /** - * Search for a reference of type "#/a/b/c" int the - * parsed JSON object + * Search for a reference of type "#/a/b/c" in the + * parsed JSON object (root) */ struct json_object *search(const char *path) { @@ -152,7 +157,7 @@ struct json_object *expand_$ref(struct path path) case json_type_array: /* expand the values of arrays */ i = 0; - n = json_object_array_length(path.object); + 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 }); @@ -170,6 +175,7 @@ struct json_object *expand_$ref(struct path path) return path.object; } +/* create c name by replacing non alpha numeric characters with underscores */ char *cify(const char *str) { char *r = strdup(str); @@ -182,10 +188,11 @@ 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]; + char *desc, c, buf[3] = {0}; size_t len; int i, pos, e; @@ -214,6 +221,7 @@ char *make_info(const char *text, int split) switch ((c = *b++)) { case 0: b--; + buf[0] = 0; break; case '/': buf[0] = '/'; @@ -260,11 +268,13 @@ char *make_info(const char *text, int split) return desc; } +/* make the description of the object */ char *make_desc(struct json_object *o) { - return make_info(json_object_to_json_string_ext(root, 0), 1); + 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; @@ -279,14 +289,15 @@ struct json_object *permissions_of_verb(struct json_object *obj) return NULL; } +/* output the array of permissions */ void print_perms() { int i, n; const char *fmtstr = cpp ? "\t%s" : "\t{ %s }"; - n = a_perms ? json_object_array_length(a_perms) : 0; + n = a_perms ? (int)json_object_array_length(a_perms) : 0; if (n) { - printf("static const struct afb_auth _afb_auths_v2_%s[] = {\n" , capi); + printf("static const struct afb_auth _afb_auths_%s[] = {\n" , capi); i = 0; while (i < n) { printf(fmtstr, json_object_get_string(json_object_array_get_idx(a_perms, i))); @@ -296,6 +307,10 @@ void print_perms() } } +/* + * search in the global object 'd_perm' the computed representation + * of the permission described either by 'obj' or 'desc' + */ struct json_object *new_perm(struct json_object *obj, const char *desc) { const char *tag; @@ -304,12 +319,15 @@ struct json_object *new_perm(struct json_object *obj, const char *desc) tag = obj ? json_object_to_json_string_ext(obj, 0) : desc; if (!json_object_object_get_ex(d_perms, tag, &y)) { + + /* creates the d_perms dico and the a_perms array */ if (!d_perms) { d_perms = json_object_new_object(); a_perms = json_object_new_array(); } - asprintf(&b, "&_afb_auths_v2_%s[%d]", capi, json_object_array_length(a_perms)); + /* creates the reference in the structure */ + asprintf(&b, "&_afb_auths_%s[%d]", capi, (int)json_object_array_length(a_perms)); x = json_object_new_string(desc); y = json_object_new_string(b); json_object_array_add(a_perms, x); @@ -323,6 +341,7 @@ struct json_object *decl_perm(struct json_object *obj); enum optype { And, Or }; +/* recursive declare and/or permissions */ struct json_object *decl_perm_a(enum optype op, struct json_object *obj) { int i, n; @@ -338,7 +357,7 @@ struct json_object *decl_perm_a(enum optype op, struct json_object *obj) opstr = op==And ? "And" : "Or"; } x = NULL; - i = n = obj ? json_object_array_length(obj) : 0; + i = n = obj ? (int)json_object_array_length(obj) : 0; while (i) { y = decl_perm(json_object_array_get_idx(obj, --i)); if (!y) @@ -354,16 +373,22 @@ struct json_object *decl_perm_a(enum optype op, struct json_object *obj) return x; } +/* declare the permission for obj */ struct json_object *decl_perm(struct json_object *obj) { char *a; + const char *fmt; struct json_object *x, *y; if (json_object_object_get_ex(d_perms, json_object_to_json_string_ext(obj, 0), &x)) return x; if (json_object_object_get_ex(obj, "permission", &x)) { - asprintf(&a, cpp ? "afb::auth_permission(\"%s\")" : ".type = afb_auth_Permission, .text = \"%s\"", json_object_get_string(x)); + if (cpp) + fmt = "afb::auth_permission(\"%s\")"; + else + fmt = ".type = afb_auth_Permission, .text = \"%s\""; + asprintf(&a, fmt, json_object_get_string(x)); y = new_perm(obj, a); free(a); } @@ -375,7 +400,11 @@ struct json_object *decl_perm(struct json_object *obj) } else if (json_object_object_get_ex(obj, "not", &x)) { x = decl_perm(x); - asprintf(&a, cpp ? "afb::auth_not(%s)" : ".type = afb_auth_Not, .first = %s", json_object_get_string(x)); + if (cpp) + fmt = "afb::auth_not(%s)"; + else + fmt = ".type = afb_auth_Not, .first = %s"; + asprintf(&a, fmt, json_object_get_string(x)); y = new_perm(obj, a); free(a); } @@ -414,7 +443,7 @@ int get_session_a(int and, struct json_object *obj) { int i, n, x, y; - n = obj ? json_object_array_length(obj) : 0; + n = obj ? (int)json_object_array_length(obj) : 0; if (n == 0) return 0; @@ -477,7 +506,7 @@ void print_session(struct json_object *p) s = p ? get_session(p) : 0; c = 1; if (s & SESSION_CHECK) { - printf("%s", "|AFB_SESSION_CHECK_V2" + c); + printf("%s", "|AFB_SESSION_CHECK" + c); c = 0; } if (s & SESSION_LOA_3 & ~SESSION_LOA_2) @@ -489,19 +518,19 @@ void print_session(struct json_object *p) else l = 0; if (l) { - printf("%s%d_V2", "|AFB_SESSION_LOA_" + c, l); + printf("%s%d", "|AFB_SESSION_LOA_" + c, l); c = 0; } if (s & SESSION_CLOSE) { - printf("%s", "|AFB_SESSION_CLOSE_V2" + c); + printf("%s", "|AFB_SESSION_CLOSE" + c); c = 0; } if (s & SESSION_RENEW) { - printf("%s", "|AFB_SESSION_REFRESH_V2" + c); + printf("%s", "|AFB_SESSION_REFRESH" + c); c = 0; } if (c) - printf("AFB_SESSION_NONE_V2"); + printf("AFB_SESSION_NONE"); } void print_verb(const char *name) @@ -511,9 +540,11 @@ void print_verb(const char *name) void print_declare_verb(const char *name, struct json_object *obj) { - printf("%s void ", scope); + if (T(scope)) + printf("%s ", scope); + printf("void "); print_verb(name); - printf("(struct afb_req req);\n"); + printf("(afb_req_t req);\n"); } void print_struct_verb(const char *name, struct json_object *obj) @@ -537,11 +568,22 @@ void print_struct_verb(const char *name, struct json_object *obj) ",\n" " .auth = %s,\n" " .info = %s,\n" - " .session = " , p && decl_perm(p) ? json_object_get_string(decl_perm(p)) : "NULL" , info ? make_info(info, 0) : "NULL" ); + if (version == 3) + printf( + " .vcbdata = NULL,\n" + ); + printf( + " .session = " + ); print_session(p); + if (version == 3) + printf( + ",\n" + " .glob = 0" + ); printf( "\n" " },\n" @@ -636,6 +678,9 @@ void process(char *filename) 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", "?"); @@ -646,7 +691,7 @@ void process(char *filename) /* get the API name */ printf( "\n" - "static const char _afb_description_v2_%s[] =\n" + "static const char _afb_description_%s[] =\n" "%s" ";\n" "\n" @@ -657,8 +702,8 @@ void process(char *filename) enum_verbs(print_declare_verb); printf( "\n" - "static const struct afb_verb_v2 _afb_verbs_v2_%s[] = {\n" - , capi + "static const struct afb_verb_v%d _afb_verbs_%s[] = {\n" + , version, capi ); enum_verbs(print_struct_verb); printf( @@ -667,33 +712,82 @@ void process(char *filename) " .callback = NULL,\n" " .auth = NULL,\n" " .info = NULL,\n" - " .session = 0\n" + ); + if (version == 3) + printf( + " .vcbdata = NULL,\n" + ); + printf( + " .session = 0" + ); + if (version == 3) + printf( + ",\n" + " .glob = 0" + ); + printf( + "\n" " }\n" "};\n" ); + + if (T(preinit) || T(init) || T(onevent)) { + printf("\n"); + if (T(preinit)) { + if (T(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); + printf("int %s(%s);\n", init, version==3 ? "afb_api_t api" : ""); + } + if (T(onevent)) { + if (T(scope)) printf("%s ", scope); + printf("void %s(%sconst char *event, struct json_object *object);\n", + onevent, version==3 ? "afb_api_t api, " : ""); + } + } + printf( "\n" - "%sconst struct afb_binding_v2 %s%s = {\n" + "%sconst struct afb_binding_v%d %s%s = {\n" " .api = \"%s\",\n" - " .specification = _afb_description_v2_%s,\n" + " .specification = _afb_description_%s,\n" " .info = %s,\n" - " .verbs = _afb_verbs_v2_%s,\n" + " .verbs = _afb_verbs_%s,\n" " .preinit = %s,\n" " .init = %s,\n" " .onevent = %s,\n" - " .noconcurrency = %d\n" - "};\n" - "\n" , priv ? "static " : "" - , priv ? "_afb_binding_v2_" : "afbBindingV2" + , version + , priv ? "_afb_binding_" : version==3 ? "afbBindingV3" : "afbBindingV2" , priv ? capi : "" , api , capi , info ? make_info(info, 0) : "NULL" , capi - , preinit ?: "NULL" - , init ?: "NULL" - , onevent ?: "NULL" + , T(preinit) ? preinit : "NULL" + , T(init) ? init : "NULL" + , T(onevent) ? onevent : "NULL" + ); + + + if (version == 3) + printf( + " .userdata = NULL,\n" + " .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) ? "\"" : "" + ); + + + printf( + " .noconcurrency = %d\n" + "};\n" + "\n" , !!noconc ); @@ -705,11 +799,25 @@ void process(char *filename) /** process the list of files or stdin if none */ int main(int ac, char **av) { + int r, w; av++; - if (*av && !(strcmp(*av, "-x") && strcmp(*av, "--cpp"))) { - cpp = 1; - av++; + + r = w = 0; + while (av[r]) { + if (!(strcmp(av[r], "-x") && strcmp(av[r], "--cpp"))) { + cpp = 1; + r++; + } else if (!strcmp(av[r], "-2")) { + version = 2; + r++; + } else if (!strcmp(av[r], "-3")) { + version = 3; + r++; + } else { + av[w++] = av[r++]; + } } + av[w] = NULL; if (!*av) process("-"); else { @@ -718,7 +826,3 @@ int main(int ac, char **av) return 0; } - - - -