diff options
author | Vincent Sanders <vincent.sanders@collabora.co.uk> | 2012-09-20 20:28:49 +0100 |
---|---|---|
committer | Vincent Sanders <vincent.sanders@collabora.co.uk> | 2012-09-20 20:28:49 +0100 |
commit | d58d0289a7b7817e2d96f4666ebb370add8d1a81 (patch) | |
tree | e00f33e3044e2254ec8c35aa0d2e2be6123b7fac | |
parent | 2133ce26a2ec07fb37a5f4cc6cab5326fdf49546 (diff) | |
download | nsgenbind-d58d0289a7b7817e2d96f4666ebb370add8d1a81.tar.gz nsgenbind-d58d0289a7b7817e2d96f4666ebb370add8d1a81.tar.bz2 |
cope with partial interfaces
-rw-r--r-- | src/jsapi-libdom.c | 57 | ||||
-rw-r--r-- | src/webidl-ast.c | 40 | ||||
-rw-r--r-- | src/webidl-ast.h | 11 | ||||
-rw-r--r-- | src/webidl-parser.y | 86 |
4 files changed, 133 insertions, 61 deletions
diff --git a/src/jsapi-libdom.c b/src/jsapi-libdom.c index 54c548c..aba6bdf 100644 --- a/src/jsapi-libdom.c +++ b/src/jsapi-libdom.c @@ -122,7 +122,7 @@ static int webidl_property_spec_cb(struct webidl_node *node, void *ctx) return 1; } else { fprintf(outfile, - " JSAPI_PS(%s, 0, JSPROP_ENUMERATE | JSPROP_SHARED),\n", + " JSAPI_PS(%s, 0, JSPROP_ENUMERATE | JSPROP_SHARED),\n", webidl_node_gettext(ident_node)); } return 0; @@ -137,6 +137,7 @@ generate_property_spec(FILE *outfile, struct webidl_node *members_node; struct webidl_node *inherit_node; + /* find interface in webidl with correct ident attached */ interface_node = webidl_node_find_type_ident(webidl_ast, WEBIDL_NODE_TYPE_INTERFACE, @@ -153,21 +154,25 @@ generate_property_spec(FILE *outfile, NULL, webidl_cmp_node_type, (void *)WEBIDL_NODE_TYPE_INTERFACE_MEMBERS); - if (members_node == NULL) { - fprintf(stderr, - "Unable to find members within interface %s\n", - interface); - return -1; - } + while (members_node != NULL) { + + fprintf(outfile," /**** %s ****/\n", interface); + + + /* for each function emit a JSAPI_FS()*/ + webidl_node_for_each_type(webidl_node_getnode(members_node), + WEBIDL_NODE_TYPE_ATTRIBUTE, + webidl_property_spec_cb, + outfile); - /* for each function emit a JSAPI_FS()*/ - webidl_node_for_each_type(webidl_node_getnode(members_node), - WEBIDL_NODE_TYPE_ATTRIBUTE, - webidl_property_spec_cb, - outfile); + members_node = webidl_node_find(webidl_node_getnode(interface_node), + members_node, + webidl_cmp_node_type, + (void *)WEBIDL_NODE_TYPE_INTERFACE_MEMBERS); + } /* check for inherited nodes and insert them too */ inherit_node = webidl_node_find(webidl_node_getnode(interface_node), NULL, @@ -195,7 +200,7 @@ output_property_spec(FILE *outfile, res = generate_property_spec(outfile, binding->interface, webidl_ast); - fprintf(outfile, " JSAPI_PS_END\n};\n"); + fprintf(outfile, " JSAPI_PS_END\n};\n"); return res; } @@ -217,7 +222,7 @@ static int webidl_func_spec_cb(struct webidl_node *node, void *ctx) */ } else { fprintf(outfile, - " JSAPI_FS(%s, 0, 0),\n", + " JSAPI_FS(%s, 0, 0),\n", webidl_node_gettext(ident_node)); } return 0; @@ -232,6 +237,7 @@ generate_function_spec(FILE *outfile, struct webidl_node *members_node; struct webidl_node *inherit_node; + /* find interface in webidl with correct ident attached */ interface_node = webidl_node_find_type_ident(webidl_ast, WEBIDL_NODE_TYPE_INTERFACE, @@ -248,20 +254,21 @@ generate_function_spec(FILE *outfile, NULL, webidl_cmp_node_type, (void *)WEBIDL_NODE_TYPE_INTERFACE_MEMBERS); - if (members_node == NULL) { - fprintf(stderr, - "Unable to find members within interface %s\n", - interface); - return -1; - } + while (members_node != NULL) { + fprintf(outfile," /**** %s ****/\n", interface); - /* for each function emit a JSAPI_FS()*/ - webidl_node_for_each_type(webidl_node_getnode(members_node), - WEBIDL_NODE_TYPE_OPERATION, - webidl_func_spec_cb, - outfile); + /* for each function emit a JSAPI_FS()*/ + webidl_node_for_each_type(webidl_node_getnode(members_node), + WEBIDL_NODE_TYPE_OPERATION, + webidl_func_spec_cb, + outfile); + members_node = webidl_node_find(webidl_node_getnode(interface_node), + members_node, + webidl_cmp_node_type, + (void *)WEBIDL_NODE_TYPE_INTERFACE_MEMBERS); + } /* check for inherited nodes and insert them too */ inherit_node = webidl_node_find(webidl_node_getnode(interface_node), diff --git a/src/webidl-ast.c b/src/webidl-ast.c index 396fd4b..aa8e279 100644 --- a/src/webidl-ast.c +++ b/src/webidl-ast.c @@ -20,6 +20,15 @@ extern int webidl__flex_debug; extern void webidl_restart(FILE*); extern int webidl_parse(struct webidl_node **webidl_ast); +struct webidl_node { + enum webidl_node_type type; + struct webidl_node *l; + union { + void *value; + struct webidl_node *node; + char *text; + } r; +}; struct webidl_node * @@ -42,6 +51,12 @@ struct webidl_node *webidl_node_new(enum webidl_node_type type, struct webidl_no return nn; } +void +webidl_node_set(struct webidl_node *node, enum webidl_node_type type, void *r) +{ + node->type = type; + node->r.value = r; +} int webidl_node_for_each_type(struct webidl_node *node, @@ -76,7 +91,7 @@ webidl_node_find(struct webidl_node *node, { struct webidl_node *ret; - if (node == NULL) { + if ((node == NULL) || (node == prev)){ return NULL; } @@ -150,17 +165,20 @@ char *webidl_node_gettext(struct webidl_node *node) struct webidl_node *webidl_node_getnode(struct webidl_node *node) { - switch(node->type) { - case WEBIDL_NODE_TYPE_ROOT: - case WEBIDL_NODE_TYPE_INTERFACE: - case WEBIDL_NODE_TYPE_INTERFACE_MEMBERS: - case WEBIDL_NODE_TYPE_ATTRIBUTE: - case WEBIDL_NODE_TYPE_OPERATION: - return node->r.node; - - default: - return NULL; + if (node != NULL) { + switch (node->type) { + case WEBIDL_NODE_TYPE_ROOT: + case WEBIDL_NODE_TYPE_INTERFACE: + case WEBIDL_NODE_TYPE_INTERFACE_MEMBERS: + case WEBIDL_NODE_TYPE_ATTRIBUTE: + case WEBIDL_NODE_TYPE_OPERATION: + return node->r.node; + default: + break; + } } + return NULL; + } static const char *webidl_node_type_to_str(enum webidl_node_type type) diff --git a/src/webidl-ast.h b/src/webidl-ast.h index 682bb27..b421615 100644 --- a/src/webidl-ast.h +++ b/src/webidl-ast.h @@ -19,14 +19,7 @@ enum webidl_node_type { WEBIDL_NODE_TYPE_OPERATION, }; -struct webidl_node { - enum webidl_node_type type; - struct webidl_node *l; - union { - struct webidl_node *node; - char *text; - } r; -}; +struct webidl_node; /** callback for search and iteration routines */ typedef int (webidl_callback_t)(struct webidl_node *node, void *ctx); @@ -35,6 +28,8 @@ int webidl_cmp_node_type(struct webidl_node *node, void *ctx); struct webidl_node *webidl_node_new(enum webidl_node_type, struct webidl_node *l, void *r); +void webidl_node_set(struct webidl_node *node, enum webidl_node_type type, void *r); + struct webidl_node *webidl_node_link(struct webidl_node *tgt, struct webidl_node *src); /* node contents acessors */ diff --git a/src/webidl-parser.y b/src/webidl-parser.y index f0f1830..d9be0b9 100644 --- a/src/webidl-parser.y +++ b/src/webidl-parser.y @@ -113,7 +113,6 @@ webidl_error(YYLTYPE *locp, struct webidl_node **winbind_ast, const char *str) %type <node> Partial %type <node> PartialDefinition -%type <node> PartialInterface %type <node> Dictionary %type <node> PartialDictionary @@ -122,9 +121,11 @@ webidl_error(YYLTYPE *locp, struct webidl_node **winbind_ast, const char *str) %type <node> Enum %type <node> Typedef %type <node> ImplementsStatement + %type <node> Interface %type <node> InterfaceMembers %type <node> InterfaceMember +%type <node> PartialInterface %type <node> CallbackOrInterface %type <node> CallbackRest @@ -137,7 +138,7 @@ webidl_error(YYLTYPE *locp, struct webidl_node **winbind_ast, const char *str) %type <node> Operation %type <node> OperationRest -%type <node> OptionalIdentifier +%type <text> OptionalIdentifier %% @@ -206,19 +207,43 @@ CallbackRestOrInterface: Interface: TOK_INTERFACE TOK_IDENTIFIER Inheritance '{' InterfaceMembers '}' ';' { - struct webidl_node *ident; - struct webidl_node *members; - struct webidl_node *inheritance = NULL; - - if ($3 != NULL) { - inheritance = webidl_node_new(WEBIDL_NODE_TYPE_INTERFACE_INHERITANCE, NULL, $3); + /* extend interface with additional members */ + struct webidl_node *interface_node; + interface_node = webidl_node_find_type_ident(*webidl_ast, + WEBIDL_NODE_TYPE_INTERFACE, + $2); + if (interface_node == NULL) { + struct webidl_node *members; + struct webidl_node *ident; + struct webidl_node *inheritance = NULL; + + if ($3 != NULL) { + inheritance = webidl_node_new(WEBIDL_NODE_TYPE_INTERFACE_INHERITANCE, NULL, $3); + } + + members = webidl_node_new(WEBIDL_NODE_TYPE_INTERFACE_MEMBERS, inheritance, $5); + + ident = webidl_node_new(WEBIDL_NODE_TYPE_IDENT, members, $2); + + $$ = webidl_node_new(WEBIDL_NODE_TYPE_INTERFACE, NULL, ident); + } else { + struct webidl_node *members; + struct webidl_node *inheritance = webidl_node_getnode(interface_node); + + if ($3 != NULL) { + inheritance = webidl_node_new(WEBIDL_NODE_TYPE_INTERFACE_INHERITANCE, inheritance, $3); + } + + members = webidl_node_new(WEBIDL_NODE_TYPE_INTERFACE_MEMBERS, + inheritance, + $5); + + /* link member node into interfaces_node */ + webidl_node_set(interface_node, + WEBIDL_NODE_TYPE_INTERFACE, + members); + $$ = NULL; /* updated existing interface do not add it again */ } - - members = webidl_node_new(WEBIDL_NODE_TYPE_INTERFACE_MEMBERS, inheritance, $5); - - ident = webidl_node_new(WEBIDL_NODE_TYPE_IDENT, members, $2); - - $$ = webidl_node_new(WEBIDL_NODE_TYPE_INTERFACE, NULL, ident); } ; @@ -241,7 +266,35 @@ PartialDefinition: PartialInterface: TOK_INTERFACE TOK_IDENTIFIER '{' InterfaceMembers '}' ';' { - $$=NULL; + /* extend interface with additional members */ + struct webidl_node *interface_node; + interface_node = webidl_node_find_type_ident(*webidl_ast, + WEBIDL_NODE_TYPE_INTERFACE, + $2); + if (interface_node == NULL) { + /* doesnt already exist so create it */ + struct webidl_node *members; + struct webidl_node *ident; + + members = webidl_node_new(WEBIDL_NODE_TYPE_INTERFACE_MEMBERS, NULL, $4); + + ident = webidl_node_new(WEBIDL_NODE_TYPE_IDENT, members, $2); + + $$ = webidl_node_new(WEBIDL_NODE_TYPE_INTERFACE, NULL, ident); + + } else { + struct webidl_node *members; + members = webidl_node_new(WEBIDL_NODE_TYPE_INTERFACE_MEMBERS, + webidl_node_getnode(interface_node), + $4); + + /* link member node into interfaces_node */ + webidl_node_set(interface_node, + WEBIDL_NODE_TYPE_INTERFACE, + members); + + $$ = NULL; /* updated existing interface do not add it again */ + } } ; @@ -289,7 +342,6 @@ DictionaryMember: PartialDictionary: TOK_DICTIONARY TOK_IDENTIFIER '{' DictionaryMembers '}' ';' { - $$=NULL; } /* [15] */ @@ -515,7 +567,7 @@ OperationRest: OptionalIdentifier: /* empty */ { - $$=NULL; + $$ = NULL; } | TOK_IDENTIFIER |