From abec5defbb553588dce1c317b74570061705f6d0 Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Mon, 16 Dec 2013 00:08:27 +0000 Subject: add flags to interface within binding --- src/jsapi-libdom-property.c | 15 ++++++---- src/jsapi-libdom.c | 71 ++++++++++++++++++++++++++++++++------------- src/nsgenbind-ast.c | 13 +++++---- src/nsgenbind-ast.h | 33 ++++++++++++++++++--- src/nsgenbind-lexer.l | 2 ++ src/nsgenbind-parser.y | 54 ++++++++++++++++++++++++++++++++-- 6 files changed, 152 insertions(+), 36 deletions(-) (limited to 'src') diff --git a/src/jsapi-libdom-property.c b/src/jsapi-libdom-property.c index 2bd3068..091b2c6 100644 --- a/src/jsapi-libdom-property.c +++ b/src/jsapi-libdom-property.c @@ -229,6 +229,7 @@ get_binding_shared_modifier(struct binding *binding, const char *type, const cha { struct genbind_node *shared_node; struct genbind_node *shared_mod_node; + enum genbind_type_modifier *shared_modifier; /* look for node matching the ident first */ shared_node = genbind_node_find_type_ident(binding->binding_list, @@ -251,9 +252,11 @@ get_binding_shared_modifier(struct binding *binding, const char *type, const cha shared_mod_node = genbind_node_find_type(genbind_node_getnode(shared_node), NULL, GENBIND_NODE_TYPE_MODIFIER); - if (shared_mod_node != NULL) { - return genbind_node_getint(shared_mod_node); + shared_modifier = (enum genbind_type_modifier *)genbind_node_getint(shared_mod_node); + if (shared_modifier != NULL) { + return *shared_modifier; } + } return GENBIND_TYPE_NONE; } @@ -1108,14 +1111,16 @@ static int typehandler_property_cb(struct genbind_node *node, void *ctx) struct genbind_node *ident_node; const char *type; struct genbind_node *mod_node; - enum genbind_type_modifier share_mod; + enum genbind_type_modifier *share_mod; int ret = 0; mod_node = genbind_node_find_type(genbind_node_getnode(node), NULL, GENBIND_NODE_TYPE_MODIFIER); - share_mod = genbind_node_getint(mod_node); - if ((share_mod & GENBIND_TYPE_TYPE) == GENBIND_TYPE_TYPE) { + share_mod = (enum genbind_type_modifier *)genbind_node_getint(mod_node); + + if ((share_mod != NULL) && + ((*share_mod & GENBIND_TYPE_TYPE) == GENBIND_TYPE_TYPE)) { /* type handler */ ident_node = genbind_node_find_type(genbind_node_getnode(node), diff --git a/src/jsapi-libdom.c b/src/jsapi-libdom.c index 97a6193..2389a57 100644 --- a/src/jsapi-libdom.c +++ b/src/jsapi-libdom.c @@ -211,6 +211,10 @@ output_epilogue(struct binding *binding) static int output_prologue(struct binding *binding) { + /* forward declare property list */ + fprintf(binding->outfile, + "static JSPropertySpec jsclass_properties[];\n\n"); + genbind_node_for_each_type(binding->gb_ast, GENBIND_NODE_TYPE_PROLOGUE, webidl_prologue_cb, @@ -728,7 +732,7 @@ output_class_new(struct binding *binding) } static int -output_jsclass(struct binding *binding) +output_forward_declarations(struct binding *binding) { /* forward declare add property */ if (binding->addproperty != NULL) { @@ -778,10 +782,12 @@ output_jsclass(struct binding *binding) "static void jsclass_finalize(JSContext *cx, JSObject *obj);\n\n"); } - /* forward declare property list */ - fprintf(binding->outfile, - "static JSPropertySpec jsclass_properties[];\n\n"); + return 0; +} +static int +output_jsclass(struct binding *binding) +{ /* output the class declaration */ HDROUTF(binding, "JSClass JSClass_%s;\n", binding->interface); @@ -860,31 +866,36 @@ output_jsclass(struct binding *binding) /* resolver */ if (binding->resolve != NULL) { - fprintf(binding->outfile, "\t(JSResolveOp)jsclass_resolve,\n"); + fprintf(binding->outfile, + "\t(JSResolveOp)jsclass_resolve,\t/* resolve */\n"); } else { - fprintf(binding->outfile, "\tJS_ResolveStub,\n"); + fprintf(binding->outfile, + "\tJS_ResolveStub,\t\t/* resolve */\n"); } - fprintf(binding->outfile, "\tJS_ConvertStub,\t/* convert */\n"); + fprintf(binding->outfile, "\tJS_ConvertStub,\t\t/* convert */\n"); if (binding->has_private || (binding->finalise != NULL)) { - fprintf(binding->outfile, "\tjsclass_finalize,\n"); + fprintf(binding->outfile, + "\tjsclass_finalize,\t/* finalizer */\n"); } else { - fprintf(binding->outfile, "\tJS_FinalizeStub,\n"); + fprintf(binding->outfile, + "\tJS_FinalizeStub,\t/* finalizer */\n"); } fprintf(binding->outfile, - "\t0,\t/* reserved */\n" - "\tNULL,\t/* checkAccess */\n" - "\tNULL,\t/* call */\n" - "\tNULL,\t/* construct */\n" - "\tNULL,\t/* xdr Object */\n" - "\tNULL,\t/* hasInstance */\n"); + "\t0,\t\t\t/* reserved */\n" + "\tNULL,\t\t\t/* checkAccess */\n" + "\tNULL,\t\t\t/* call */\n" + "\tNULL,\t\t\t/* construct */\n" + "\tNULL,\t\t\t/* xdr Object */\n" + "\tNULL,\t\t\t/* hasInstance */\n"); /* trace/mark */ if (binding->mark != NULL) { - fprintf(binding->outfile, "\tJSAPI_JSCLASS_MARKOP(jsclass_mark),\n"); + fprintf(binding->outfile, + "\tJSAPI_JSCLASS_MARKOP(jsclass_mark),\n"); } else { - fprintf(binding->outfile, "\tNULL, /* trace/mark */\n"); + fprintf(binding->outfile, "\tNULL,\t\t\t/* trace/mark */\n"); } fprintf(binding->outfile, @@ -1011,6 +1022,7 @@ binding_has_private(struct genbind_node *binding_list) return false; } +/* determine if the binding has a global api marker */ static bool binding_has_global(struct binding *binding) { @@ -1034,6 +1046,7 @@ binding_new(struct options *options, struct binding *nb; struct genbind_node *interface_node; struct genbind_node *binding_list; + struct genbind_node *binding_ident; char *hdrguard = NULL; struct webidl_node *webidl_ast = NULL; int res; @@ -1043,6 +1056,7 @@ binding_new(struct options *options, return NULL; } + /* find the first interface node - there must be at least one */ interface_node = genbind_node_find_type(binding_list, NULL, GENBIND_NODE_TYPE_BINDING_INTERFACE); @@ -1050,7 +1064,18 @@ binding_new(struct options *options, return NULL; } - /* walk ast and load any web IDL files required */ + /* get the binding identifier */ + /* @todo it should be possible to specify this as part of the + * binding instead of just using the first interface + */ + binding_ident = genbind_node_find_type(genbind_node_getnode(interface_node), + NULL, + GENBIND_NODE_TYPE_IDENT); + if (binding_ident == NULL) { + return NULL; + } + + /* walk AST and load any web IDL files required */ res = read_webidl(genbind_ast, &webidl_ast); if (res != 0) { fprintf(stderr, "Error reading Web IDL files\n"); @@ -1077,7 +1102,8 @@ binding_new(struct options *options, nb->gb_ast = genbind_ast; nb->wi_ast = webidl_ast; - nb->interface = genbind_node_gettext(interface_node); + /* @todo binding name should not be called interface */ + nb->interface = genbind_node_gettext(binding_ident); nb->outfile = options->outfilehandle; nb->srcfile = options->outfilehandle; nb->hdrfile = options->hdrfilehandle; @@ -1160,6 +1186,11 @@ jsapi_libdom_output(struct options *options, return 70; } + res = output_forward_declarations(binding); + if (res) { + return 75; + } + res = output_jsclass(binding); if (res) { return 80; @@ -1170,7 +1201,7 @@ jsapi_libdom_output(struct options *options, return 85; } - /* user code outout just before function bodies emitted */ + /* user code output just before function bodies emitted */ res = output_prologue(binding); if (res) { return 89; diff --git a/src/nsgenbind-ast.c b/src/nsgenbind-ast.c index 851cbeb..d20975f 100644 --- a/src/nsgenbind-ast.c +++ b/src/nsgenbind-ast.c @@ -211,7 +211,6 @@ char *genbind_node_gettext(struct genbind_node *node) case GENBIND_NODE_TYPE_EPILOGUE: case GENBIND_NODE_TYPE_IDENT: case GENBIND_NODE_TYPE_TYPE: - case GENBIND_NODE_TYPE_BINDING_INTERFACE: case GENBIND_NODE_TYPE_CBLOCK: return node->r.text; @@ -231,6 +230,8 @@ struct genbind_node *genbind_node_getnode(struct genbind_node *node) case GENBIND_NODE_TYPE_BINDING_PRIVATE: case GENBIND_NODE_TYPE_BINDING_INTERNAL: case GENBIND_NODE_TYPE_BINDING_PROPERTY: + case GENBIND_NODE_TYPE_BINDING_INTERFACE: + case GENBIND_NODE_TYPE_BINDING_INTERFACE_FLAGS: case GENBIND_NODE_TYPE_OPERATION: case GENBIND_NODE_TYPE_API: case GENBIND_NODE_TYPE_GETTER: @@ -245,19 +246,18 @@ struct genbind_node *genbind_node_getnode(struct genbind_node *node) } -int genbind_node_getint(struct genbind_node *node) +int *genbind_node_getint(struct genbind_node *node) { if (node != NULL) { switch(node->type) { case GENBIND_NODE_TYPE_MODIFIER: - return node->r.number; + return &node->r.number; default: break; } } - return -1; - + return NULL; } static const char *genbind_node_type_to_str(enum genbind_node_type type) @@ -296,6 +296,9 @@ static const char *genbind_node_type_to_str(enum genbind_node_type type) case GENBIND_NODE_TYPE_BINDING_INTERFACE: return "Interface"; + case GENBIND_NODE_TYPE_BINDING_INTERFACE_FLAGS: + return "Flags"; + case GENBIND_NODE_TYPE_BINDING_PROPERTY: return "Property"; diff --git a/src/nsgenbind-ast.h b/src/nsgenbind-ast.h index 6513f7f..d59aeba 100644 --- a/src/nsgenbind-ast.h +++ b/src/nsgenbind-ast.h @@ -26,6 +26,7 @@ enum genbind_node_type { GENBIND_NODE_TYPE_BINDING_PRIVATE, GENBIND_NODE_TYPE_BINDING_INTERNAL, GENBIND_NODE_TYPE_BINDING_INTERFACE, + GENBIND_NODE_TYPE_BINDING_INTERFACE_FLAGS, GENBIND_NODE_TYPE_BINDING_PROPERTY, GENBIND_NODE_TYPE_API, GENBIND_NODE_TYPE_OPERATION, @@ -41,6 +42,11 @@ enum genbind_type_modifier { GENBIND_TYPE_TYPE_UNSHARED = 3, /**< identifies a unshared type handler */ }; +/* interface flags */ +enum genbind_interface_flags { + GENBIND_INTERFACE_FLAG_NONE = 0, + GENBIND_INTERFACE_FLAG_GLOBAL = 1, /**< interface is global */ +}; struct genbind_node; @@ -111,8 +117,8 @@ genbind_node_find_type_ident(struct genbind_node *node, * @param prev The node at which to stop the search, either NULL to * search the full tree depth (initial search) or the result * of a previous search to continue. - * @param nodetype The type of node to seach for - * @param type The text to match the type child node to + * @param nodetype The type of node to seach for. + * @param type The text to match the type child node to. */ struct genbind_node * genbind_node_find_type_type(struct genbind_node *node, @@ -122,9 +128,28 @@ genbind_node_find_type_type(struct genbind_node *node, int genbind_node_for_each_type(struct genbind_node *node, enum genbind_node_type type, genbind_callback_t *cb, void *ctx); -char *genbind_node_gettext(struct genbind_node *node); +/** get a nodes node list content + * + * @param node The nodes to get node list from + * @return pointer to the node list or NULL if the node does not contain a list + */ struct genbind_node *genbind_node_getnode(struct genbind_node *node); -int genbind_node_getint(struct genbind_node *node); + +/** get a nodes text content + * + * @param node The nodes to get text from + * @return pointer to the node text or NULL if the node is not of type + * text or is empty. + */ +char *genbind_node_gettext(struct genbind_node *node); + +/** get a nodes integer value + * + * @param node The nodes to get integer from + * @return pointer to the node value or NULL if the node is not of type + * int or is empty. + */ +int *genbind_node_getint(struct genbind_node *node); #ifdef _WIN32 #define NEED_STRNDUP 1 diff --git a/src/nsgenbind-lexer.l b/src/nsgenbind-lexer.l index 8189a72..4b5e225 100644 --- a/src/nsgenbind-lexer.l +++ b/src/nsgenbind-lexer.l @@ -104,6 +104,8 @@ binding return TOK_BINDING; interface return TOK_INTERFACE; +flags return TOK_FLAGS; + type return TOK_TYPE; private return TOK_PRIVATE; diff --git a/src/nsgenbind-parser.y b/src/nsgenbind-parser.y index b9ec23b..b37ab9d 100644 --- a/src/nsgenbind-parser.y +++ b/src/nsgenbind-parser.y @@ -54,6 +54,7 @@ char *errtxt; %token TOK_GETTER %token TOK_SETTER %token TOK_INTERFACE +%token TOK_FLAGS %token TOK_TYPE %token TOK_PRIVATE %token TOK_INTERNAL @@ -84,6 +85,9 @@ char *errtxt; %type Private %type Internal %type Interface +%type InterfaceArgs +%type InterfaceArg +%type InterfaceFlags %type Property %type Operation %type Api @@ -91,6 +95,7 @@ char *errtxt; %type Setter + %% Input @@ -260,7 +265,7 @@ Setter Binding : - TOK_BINDING TOK_IDENTIFIER '{' BindingArgs '}' + TOK_BINDING TOK_IDENTIFIER '{' BindingArgs '}' { $$ = genbind_new_node(GENBIND_NODE_TYPE_BINDING, NULL, @@ -313,7 +318,52 @@ Interface : TOK_INTERFACE TOK_IDENTIFIER ';' { - $$ = genbind_new_node(GENBIND_NODE_TYPE_BINDING_INTERFACE, NULL, $2); + $$ = genbind_new_node(GENBIND_NODE_TYPE_BINDING_INTERFACE, NULL, + genbind_new_node(GENBIND_NODE_TYPE_IDENT, NULL, $2)); + } + | + TOK_INTERFACE TOK_IDENTIFIER '{' '}' + { + $$ = genbind_new_node(GENBIND_NODE_TYPE_BINDING_INTERFACE, NULL, + genbind_new_node(GENBIND_NODE_TYPE_IDENT, NULL, $2)); + } + | + TOK_INTERFACE TOK_IDENTIFIER '{' InterfaceArgs '}' + { + $$ = genbind_new_node(GENBIND_NODE_TYPE_BINDING_INTERFACE, + NULL, + genbind_new_node(GENBIND_NODE_TYPE_IDENT, $4, $2)); + } + ; + +InterfaceArgs + : + InterfaceArg + | + InterfaceArgs InterfaceArg + { + $$ = genbind_node_link($2, $1); + } + ; + +InterfaceArg + : + TOK_FLAGS InterfaceFlags ';' + { + $$ = genbind_new_node(GENBIND_NODE_TYPE_BINDING_INTERFACE_FLAGS, NULL, $2); + } + ; + +InterfaceFlags + : + TOK_IDENTIFIER + { + $$ = genbind_new_node(GENBIND_NODE_TYPE_IDENT, NULL, $1); + } + | + InterfaceFlags ',' TOK_IDENTIFIER + { + $$ = genbind_new_node(GENBIND_NODE_TYPE_IDENT, $1, $3); } ; -- cgit v1.2.3