summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Sanders <vincent.sanders@collabora.co.uk>2012-09-20 20:28:49 +0100
committerVincent Sanders <vincent.sanders@collabora.co.uk>2012-09-20 20:28:49 +0100
commitd58d0289a7b7817e2d96f4666ebb370add8d1a81 (patch)
treee00f33e3044e2254ec8c35aa0d2e2be6123b7fac
parent2133ce26a2ec07fb37a5f4cc6cab5326fdf49546 (diff)
downloadnsgenbind-d58d0289a7b7817e2d96f4666ebb370add8d1a81.tar.gz
nsgenbind-d58d0289a7b7817e2d96f4666ebb370add8d1a81.tar.bz2
cope with partial interfaces
-rw-r--r--src/jsapi-libdom.c57
-rw-r--r--src/webidl-ast.c40
-rw-r--r--src/webidl-ast.h11
-rw-r--r--src/webidl-parser.y86
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