From 5755930ae93b6305b40620fff0e90bc2e4c64b46 Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Sat, 7 Dec 2013 14:28:19 +0000 Subject: move binding type from explicit statement into declaration. As a side effect the binding declaration changes and looses its (unused) name/identifier --- doc/example.bnd | 10 ++- src/jsapi-libdom.c | 121 ++++++++++++----------------------- src/jsapi-libdom.h | 6 +- src/nsgenbind-parser.y | 13 +--- src/nsgenbind.c | 86 +++++++++++++++++++++---- src/options.h | 4 ++ test/data/bindings/htmldocument.bnd | 3 +- test/data/bindings/htmldocument2.bnd | 4 +- test/data/bindings/window.bnd | 3 +- 9 files changed, 130 insertions(+), 120 deletions(-) diff --git a/doc/example.bnd b/doc/example.bnd index 690eace..6003f0d 100644 --- a/doc/example.bnd +++ b/doc/example.bnd @@ -53,17 +53,15 @@ epilogue %{ #include "dom.bnd" -/* this block describes the binding to be generated +/* This block describes the binding to be generated * * Depending on the type of binding being generated multiple blocks * may be allowed. * - * Note: the js_libdom (javascript to libdom) binding as currently - * implemented only allows for a single binding per file, this may - * be improved in future. + * Note: the jsapi_libdom (spidermonkey javascript to libdom) binding + * is the only type currently implemented */ -binding example { - type js_libdom; /* the binding type */ +binding jsapi_libdom { interface Navigator; /* The WebIDL interface to generate a binding for */ diff --git a/src/jsapi-libdom.c b/src/jsapi-libdom.c index 7104a83..97a6193 100644 --- a/src/jsapi-libdom.c +++ b/src/jsapi-libdom.c @@ -285,7 +285,7 @@ output_api_operations(struct binding *binding) "\n" "\tprivate = JS_GetInstancePrivate(cx, obj, &JSClass_%s, NULL);\n", binding->interface); - + if (options->dbglog) { fprintf(binding->outfile, "\tJSLOG(\"jscontext:%%p jsobject:%%p private:%%p\", cx, obj, private);\n"); @@ -320,7 +320,7 @@ output_api_operations(struct binding *binding) "\n" "\tprivate = JS_GetInstancePrivate(cx, obj, &JSClass_%s, NULL);\n", binding->interface); - + if (options->dbglog) { fprintf(binding->outfile, "\tJSLOG(\"jscontext:%%p jsobject:%%p private:%%p\", cx, obj, private);\n"); @@ -355,7 +355,7 @@ output_api_operations(struct binding *binding) "\n" "\tprivate = JS_GetInstancePrivate(cx, obj, &JSClass_%s, NULL);\n", binding->interface); - + if (options->dbglog) { fprintf(binding->outfile, "\tJSLOG(\"jscontext:%%p jsobject:%%p private:%%p\", cx, obj, private);\n"); @@ -390,7 +390,7 @@ output_api_operations(struct binding *binding) "\n" "\tprivate = JS_GetInstancePrivate(cx, obj, &JSClass_%s, NULL);\n", binding->interface); - + if (options->dbglog) { fprintf(binding->outfile, "\tJSLOG(\"jscontext:%%p jsobject:%%p private:%%p\", cx, obj, private);\n"); @@ -893,24 +893,27 @@ output_jsclass(struct binding *binding) return 0; } +/** generate structure definition for internal class data + * + * Every javascript object instance has an internal context to keep + * track of its state in object terms this would be considered the + * "this" pointer giving access to the classes members. + * + * Member access can be considered protected as all interfaces + * (classes) and subclasses generated within this binding have access + * to members. + * + * @param binding the binding to generate the structure for. + * @return 0 on success with output written and -1 on error. + */ static int output_private_declaration(struct binding *binding) { - struct genbind_node *type_node; if (!binding->has_private) { return 0; } - type_node = genbind_node_find(binding->binding_list, - NULL, - genbind_cmp_node_type, - (void *)GENBIND_NODE_TYPE_TYPE); - - if (type_node == NULL) { - return -1; - } - fprintf(binding->outfile, "struct jsclass_private {\n"); genbind_node_for_each_type(binding->binding_list, @@ -1024,40 +1027,22 @@ binding_has_global(struct binding *binding) } static struct binding * -binding_new(char *outfilename, - char *hdrfilename, - struct genbind_node *genbind_ast) +binding_new(struct options *options, + struct genbind_node *genbind_ast, + struct genbind_node *binding_node) { struct binding *nb; - struct genbind_node *binding_node; - struct genbind_node *binding_list; - struct genbind_node *ident_node; struct genbind_node *interface_node; - FILE *outfile = NULL; /* output source file */ - FILE *hdrfile = NULL; /* output header file */ + struct genbind_node *binding_list; char *hdrguard = NULL; struct webidl_node *webidl_ast = NULL; int res; - binding_node = genbind_node_find_type(genbind_ast, - NULL, - GENBIND_NODE_TYPE_BINDING); - if (binding_node == NULL) { - return NULL; - } - binding_list = genbind_node_getnode(binding_node); if (binding_list == NULL) { return NULL; } - ident_node = genbind_node_find_type(binding_list, - NULL, - GENBIND_NODE_TYPE_IDENT); - if (ident_node == NULL) { - return NULL; - } - interface_node = genbind_node_find_type(binding_list, NULL, GENBIND_NODE_TYPE_BINDING_INTERFACE); @@ -1072,37 +1057,16 @@ binding_new(char *outfilename, return NULL; } - /* open output file */ - if (outfilename == NULL) { - outfile = stdout; - } else { - outfile = fopen(outfilename, "w"); - } - if (outfile == NULL) { - fprintf(stderr, "Error opening source output %s: %s\n", - outfilename, - strerror(errno)); - return NULL; - } - - /* output header file if required */ - if (hdrfilename != NULL) { + /* header guard */ + if (options->hdrfilename != NULL) { int guardlen; int pos; - hdrfile = fopen(hdrfilename, "w"); - if (hdrfile == NULL) { - fprintf(stderr, "Error opening header output %s: %s\n", - hdrfilename, - strerror(errno)); - fclose(outfile); - return NULL; - } - guardlen = strlen(hdrfilename); + guardlen = strlen(options->hdrfilename); hdrguard = calloc(1, guardlen + 1); for (pos = 0; pos < guardlen; pos++) { - if (isalpha(hdrfilename[pos])) { - hdrguard[pos] = toupper(hdrfilename[pos]); + if (isalpha(options->hdrfilename[pos])) { + hdrguard[pos] = toupper(options->hdrfilename[pos]); } else { hdrguard[pos] = '_'; } @@ -1113,11 +1077,10 @@ binding_new(char *outfilename, nb->gb_ast = genbind_ast; nb->wi_ast = webidl_ast; - nb->name = genbind_node_gettext(ident_node); nb->interface = genbind_node_gettext(interface_node); - nb->outfile = outfile; - nb->srcfile = outfile; - nb->hdrfile = hdrfile; + nb->outfile = options->outfilehandle; + nb->srcfile = options->outfilehandle; + nb->hdrfile = options->hdrfilehandle; nb->hdrguard = hdrguard; nb->has_private = binding_has_private(binding_list); nb->has_global = binding_has_global(nb); @@ -1145,14 +1108,14 @@ binding_new(char *outfilename, "setproperty"); nb->enumerate = genbind_node_find_type_ident(genbind_ast, - NULL, - GENBIND_NODE_TYPE_API, - "enumerate"); + NULL, + GENBIND_NODE_TYPE_API, + "enumerate"); nb->resolve = genbind_node_find_type_ident(genbind_ast, - NULL, - GENBIND_NODE_TYPE_API, - "resolve"); + NULL, + GENBIND_NODE_TYPE_API, + "resolve"); nb->finalise = genbind_node_find_type_ident(genbind_ast, NULL, @@ -1160,23 +1123,23 @@ binding_new(char *outfilename, "finalise"); nb->mark = genbind_node_find_type_ident(genbind_ast, - NULL, - GENBIND_NODE_TYPE_API, - "mark"); + NULL, + GENBIND_NODE_TYPE_API, + "mark"); return nb; } int -jsapi_libdom_output(char *outfilename, - char *hdrfilename, - struct genbind_node *genbind_ast) +jsapi_libdom_output(struct options *options, + struct genbind_node *genbind_ast, + struct genbind_node *binding_node) { int res; struct binding *binding; /* get general binding information used in output */ - binding = binding_new(outfilename, hdrfilename, genbind_ast); + binding = binding_new(options, genbind_ast, binding_node); if (binding == NULL) { return 40; } diff --git a/src/jsapi-libdom.h b/src/jsapi-libdom.h index 7db664d..5a93ff1 100644 --- a/src/jsapi-libdom.h +++ b/src/jsapi-libdom.h @@ -9,12 +9,12 @@ #ifndef nsgenbind_jsapi_libdom_h #define nsgenbind_jsapi_libdom_h +struct options; + struct binding { struct genbind_node *gb_ast; /* root node of binding AST */ struct webidl_node *wi_ast; /* root node of webidl AST */ - - const char *name; /* name of the binding */ const char *interface; /* webidl interface binding is for */ bool has_private; /* true if the binding requires a private structure */ @@ -41,7 +41,7 @@ struct binding { }; /** Generate binding between jsapi and netsurf libdom */ -int jsapi_libdom_output(char *outfile, char *hdrfile, struct genbind_node *genbind_root); +int jsapi_libdom_output(struct options *options, struct genbind_node *genbind_ast, struct genbind_node *binding_node); /** output code block from a node */ void output_code_block(struct binding *binding, struct genbind_node *codelist); diff --git a/src/nsgenbind-parser.y b/src/nsgenbind-parser.y index 46bc4f3..b9ec23b 100644 --- a/src/nsgenbind-parser.y +++ b/src/nsgenbind-parser.y @@ -81,7 +81,6 @@ char *errtxt; %type Binding %type BindingArgs %type BindingArg -%type Type %type Private %type Internal %type Interface @@ -265,7 +264,7 @@ Binding { $$ = genbind_new_node(GENBIND_NODE_TYPE_BINDING, NULL, - genbind_new_node(GENBIND_NODE_TYPE_IDENT, $4, $2)); + genbind_new_node(GENBIND_NODE_TYPE_TYPE, $4, $2)); } ; @@ -281,8 +280,6 @@ BindingArgs BindingArg : - Type - | Private | Internal @@ -292,14 +289,6 @@ BindingArg Property ; -Type - : - TOK_TYPE TOK_IDENTIFIER ';' - { - $$ = genbind_new_node(GENBIND_NODE_TYPE_TYPE, NULL, $2); - } - ; - Private : TOK_PRIVATE TOK_STRING_LITERAL TOK_IDENTIFIER ';' diff --git a/src/nsgenbind.c b/src/nsgenbind.c index d993646..636c22b 100644 --- a/src/nsgenbind.c +++ b/src/nsgenbind.c @@ -65,12 +65,12 @@ static struct options* process_cmdline(int argc, char **argv) break; default: /* '?' */ - fprintf(stderr, + fprintf(stderr, "Usage: %s [-v] [-g] [-D] [-W] [-d depfilename] [-I idlpath] [-o filename] [-h headerfile] inputfile\n", argv[0]); free(options); return NULL; - + } } @@ -86,6 +86,27 @@ static struct options* process_cmdline(int argc, char **argv) } +static int generate_binding(struct genbind_node *binding_node, void *ctx) +{ + struct genbind_node *genbind_root = ctx; + char *type; + int res = 10; + + type = genbind_node_gettext( + genbind_node_find_type( + genbind_node_getnode(binding_node), + NULL, + GENBIND_NODE_TYPE_TYPE)); + + if (strcmp(type, "jsapi_libdom") == 0) { + res = jsapi_libdom_output(options, genbind_root, binding_node); + } else { + fprintf(stderr, "Error: unsupported binding type \"%s\"\n", type); + } + + return res; +} + int main(int argc, char **argv) { int res; @@ -96,9 +117,9 @@ int main(int argc, char **argv) return 1; /* bad commandline */ } - if (options->verbose && + if (options->verbose && (options->outfilename == NULL)) { - fprintf(stderr, + fprintf(stderr, "Error: output to stdout with verbose logging would fail\n"); return 2; } @@ -117,6 +138,7 @@ int main(int argc, char **argv) return 3; } + /* open dependancy file */ if (options->depfilename != NULL) { options->depfilehandle = fopen(options->depfilename, "w"); if (options->depfilehandle == NULL) { @@ -129,19 +151,61 @@ int main(int argc, char **argv) options->outfilename); } + /* parse input and generate dependancy */ res = genbind_parsefile(options->infilename, &genbind_root); if (res != 0) { fprintf(stderr, "Error: parse failed with code %d\n", res); return res; } + /* dependancy generation complete */ + if (options->depfilehandle != NULL) { + fputc('\n', options->depfilehandle); + fclose(options->depfilehandle); + } + + + /* open output file */ + if (options->outfilename == NULL) { + options->outfilehandle = stdout; + } else { + options->outfilehandle = fopen(options->outfilename, "w"); + } + if (options->outfilehandle == NULL) { + fprintf(stderr, "Error opening source output %s: %s\n", + options->outfilename, + strerror(errno)); + return 5; + } + + /* open output header file if required */ + if (options->hdrfilename != NULL) { + options->hdrfilehandle = fopen(options->hdrfilename, "w"); + if (options->hdrfilehandle == NULL) { + fprintf(stderr, "Error opening header output %s: %s\n", + options->hdrfilename, + strerror(errno)); + /* close and unlink output file */ + fclose(options->outfilehandle); + if (options->outfilename != NULL) { + unlink(options->outfilename); + } + return 6; + } + } else { + options->hdrfilehandle = NULL; + } + + /* dump the AST */ if (options->verbose) { genbind_ast_dump(genbind_root, 0); } - res = jsapi_libdom_output(options->outfilename, - options->hdrfilename, - genbind_root); + /* generate output for each binding */ + res = genbind_node_for_each_type(genbind_root, + GENBIND_NODE_TYPE_BINDING, + generate_binding, + genbind_root); if (res != 0) { fprintf(stderr, "Error: output failed with code %d\n", res); if (options->outfilename != NULL) { @@ -149,14 +213,10 @@ int main(int argc, char **argv) } if (options->hdrfilename != NULL) { unlink(options->hdrfilename); - } + } return res; } - if (options->depfilehandle != NULL) { - fputc('\n', options->depfilehandle); - fclose(options->depfilehandle); - } return 0; -} +} diff --git a/src/options.h b/src/options.h index 13c02be..e002a11 100644 --- a/src/options.h +++ b/src/options.h @@ -14,10 +14,14 @@ struct options { char *infilename; /**< binding source */ char *outfilename; /**< output source file */ + FILE *outfilehandle; /**< output file handle */ + char *hdrfilename; /**< output header file */ + FILE *hdrfilehandle; /**< output file handle */ char *depfilename; /**< dependancy output*/ FILE *depfilehandle; /**< dependancy file handle */ + char *idlpath; /**< path to IDL files */ bool verbose; /**< verbose processing */ diff --git a/test/data/bindings/htmldocument.bnd b/test/data/bindings/htmldocument.bnd index 8f85ca3..933695e 100644 --- a/test/data/bindings/htmldocument.bnd +++ b/test/data/bindings/htmldocument.bnd @@ -31,8 +31,7 @@ operation write %{ } %} -binding document { - type js_libdom; /* the binding type */ +binding jsapi_libdom { /* parameters to constructor value stored in private * context structure. diff --git a/test/data/bindings/htmldocument2.bnd b/test/data/bindings/htmldocument2.bnd index e7955d9..63deafd 100644 --- a/test/data/bindings/htmldocument2.bnd +++ b/test/data/bindings/htmldocument2.bnd @@ -26,9 +26,7 @@ operation write %{ } %} -binding document { - type js_libdom; /* the binding type */ - +binding jsapi_libdom { /* parameters to constructor value stored in private * context structure. */ diff --git a/test/data/bindings/window.bnd b/test/data/bindings/window.bnd index e59f65a..2f26f56 100644 --- a/test/data/bindings/window.bnd +++ b/test/data/bindings/window.bnd @@ -27,8 +27,7 @@ epilogue %{ #include "dom.bnd" -binding window { - type js_libdom; /* the binding type */ +binding jsapi_libdom { interface Window; /* Web IDL interface to generate */ -- cgit v1.2.3