diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/jsapi-libdom-function.c | 24 | ||||
-rw-r--r-- | src/jsapi-libdom-property.c | 47 | ||||
-rw-r--r-- | src/jsapi-libdom.c | 4 | ||||
-rw-r--r-- | src/webidl-ast.c | 125 | ||||
-rw-r--r-- | src/webidl-ast.h | 3 |
5 files changed, 127 insertions, 76 deletions
diff --git a/src/jsapi-libdom-function.c b/src/jsapi-libdom-function.c index 4970b48..5540b0e 100644 --- a/src/jsapi-libdom-function.c +++ b/src/jsapi-libdom-function.c @@ -45,13 +45,6 @@ static int webidl_func_spec_cb(struct webidl_node *node, void *ctx) static int generate_function_spec(struct binding *binding, const char *interface); -/* callback to emit implements operator spec */ -static int webidl_function_spec_implements_cb(struct webidl_node *node, void *ctx) -{ - struct binding *binding = ctx; - - return generate_function_spec(binding, webidl_node_gettext(node)); -} static int generate_function_spec(struct binding *binding, const char *interface) @@ -104,13 +97,6 @@ generate_function_spec(struct binding *binding, const char *interface) webidl_node_gettext(inherit_node)); } - if (res == 0) { - res = webidl_node_for_each_type(webidl_node_getnode(interface_node), - WEBIDL_NODE_TYPE_INTERFACE_IMPLEMENTS, - webidl_function_spec_implements_cb, - binding); - } - return res; } @@ -878,14 +864,6 @@ output_function_body(struct binding *binding, res = webidl_implements_cb(inherit_node, binding); } - if (res == 0) { - res = webidl_node_for_each_type( - webidl_node_getnode(interface_node), - WEBIDL_NODE_TYPE_INTERFACE_IMPLEMENTS, - webidl_implements_cb, - binding); - } - return res; } @@ -893,7 +871,7 @@ int output_function_bodies(struct binding *binding) { int inf; - int res; + int res = 0; for (inf=0; inf < binding->interfacec; inf++) { if (binding->interfaces[inf].inherit_idx == -1) { diff --git a/src/jsapi-libdom-property.c b/src/jsapi-libdom-property.c index df296cf..93ffcc5 100644 --- a/src/jsapi-libdom-property.c +++ b/src/jsapi-libdom-property.c @@ -131,14 +131,6 @@ webidl_property_tinyid_cb(struct webidl_node *node, void *ctx) return 0; } -/* callback to emit implements property spec */ -static int -webidl_property_tinyid_implements_cb(struct webidl_node *node, void *ctx) -{ - struct binding *binding = ctx; - - return generate_property_tinyid(binding, webidl_node_gettext(node)); -} static int generate_property_tinyid(struct binding *binding, const char *interface) @@ -190,13 +182,6 @@ generate_property_tinyid(struct binding *binding, const char *interface) res = generate_property_tinyid(binding, webidl_node_gettext(inherit_node)); } - if (res == 0) { - res = webidl_node_for_each_type(webidl_node_getnode(interface_node), - WEBIDL_NODE_TYPE_INTERFACE_IMPLEMENTS, - webidl_property_tinyid_implements_cb, - binding); - } - return res; } @@ -429,13 +414,6 @@ static int webidl_property_spec_cb(struct webidl_node *node, void *ctx) } -/* callback to emit implements property spec */ -static int webidl_property_spec_implements_cb(struct webidl_node *node, void *ctx) -{ - struct binding *binding = ctx; - - return generate_property_spec(binding, webidl_node_gettext(node)); -} static int generate_property_spec(struct binding *binding, const char *interface) @@ -488,13 +466,6 @@ generate_property_spec(struct binding *binding, const char *interface) webidl_node_gettext(inherit_node)); } - if (res == 0) { - res = webidl_node_for_each_type(webidl_node_getnode(interface_node), - WEBIDL_NODE_TYPE_INTERFACE_IMPLEMENTS, - webidl_property_spec_implements_cb, - binding); - } - return res; } @@ -954,17 +925,6 @@ static int webidl_property_body_cb(struct webidl_node *node, void *ctx) } - -/* callback to emit implements property bodys */ -static int webidl_implements_cb(struct webidl_node *node, void *ctx) -{ - struct binding *binding = ctx; - - return generate_property_body(binding, webidl_node_gettext(node)); -} - - - static int generate_property_body(struct binding *binding, const char *interface) { @@ -1018,13 +978,6 @@ generate_property_body(struct binding *binding, const char *interface) webidl_node_gettext(inherit_node)); } - if (res == 0) { - res = webidl_node_for_each_type(webidl_node_getnode(interface_node), - WEBIDL_NODE_TYPE_INTERFACE_IMPLEMENTS, - webidl_implements_cb, - binding); - } - return res; } diff --git a/src/jsapi-libdom.c b/src/jsapi-libdom.c index 1bb6d28..5e994b9 100644 --- a/src/jsapi-libdom.c +++ b/src/jsapi-libdom.c @@ -47,6 +47,10 @@ read_webidl(struct genbind_node *genbind_ast, struct webidl_node **webidl_ast) webidl_file_cb, webidl_ast); + if (res == 0) { + res = webidl_intercalate_implements(*webidl_ast); + } + /* debug dump of web idl AST */ if (options->verbose) { webidl_ast_dump(*webidl_ast, 0); diff --git a/src/webidl-ast.c b/src/webidl-ast.c index 8acb2fb..945b5fa 100644 --- a/src/webidl-ast.c +++ b/src/webidl-ast.c @@ -21,8 +21,8 @@ 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; + enum webidl_node_type type; /* the type of the node */ + struct webidl_node *l; /* link to the next sibling node */ union { void *value; struct webidl_node *node; /* node has a list of nodes */ @@ -223,6 +223,7 @@ webidl_node_find_type(struct webidl_node *node, } +/* exported interface defined in webidl-ast.h */ struct webidl_node * webidl_node_find_type_ident(struct webidl_node *root_node, enum webidl_node_type type, @@ -250,6 +251,7 @@ webidl_node_find_type_ident(struct webidl_node *root_node, } +/* exported interface defined in webidl-ast.h */ char *webidl_node_gettext(struct webidl_node *node) { if (node != NULL) { @@ -261,12 +263,13 @@ char *webidl_node_gettext(struct webidl_node *node) return node->r.text; default: - break; + break; } } return NULL; } +/* exported interface defined in webidl-ast.h */ int webidl_node_getint(struct webidl_node *node) { @@ -285,12 +288,14 @@ webidl_node_getint(struct webidl_node *node) } +/* exported interface defined in webidl-ast.h */ enum webidl_node_type webidl_node_gettype(struct webidl_node *node) { return node->type; } +/* exported interface defined in webidl-ast.h */ struct webidl_node *webidl_node_getnode(struct webidl_node *node) { if (node != NULL) { @@ -314,6 +319,7 @@ struct webidl_node *webidl_node_getnode(struct webidl_node *node) } +/* exported interface defined in webidl-ast.h */ static const char *webidl_node_type_to_str(enum webidl_node_type type) { switch(type) { @@ -381,6 +387,7 @@ static const char *webidl_node_type_to_str(enum webidl_node_type type) } +/* exported interface defined in webidl-ast.h */ int webidl_ast_dump(struct webidl_node *node, int indent) { const char *SPACES=" "; char *txt; @@ -408,18 +415,19 @@ int webidl_ast_dump(struct webidl_node *node, int indent) return 0; } +/* exported interface defined in webidl-ast.h */ static FILE *idlopen(const char *filename) { FILE *idlfile; char *fullname; - int fulllen; + int fulllen; if (options->idlpath == NULL) { if (options->verbose) { printf("Opening IDL file %s\n", filename); } return fopen(filename, "r"); - } + } fulllen = strlen(options->idlpath) + strlen(filename) + 2; fullname = malloc(fulllen); @@ -429,10 +437,11 @@ static FILE *idlopen(const char *filename) } idlfile = fopen(fullname, "r"); free(fullname); - + return idlfile; } +/* exported interface defined in webidl-ast.h */ int webidl_parsefile(char *filename, struct webidl_node **webidl_ast) { @@ -457,3 +466,107 @@ int webidl_parsefile(char *filename, struct webidl_node **webidl_ast) /* parse the file */ return webidl_parse(webidl_ast); } + +/* unlink a child node from a parent */ +static int +webidl_unlink(struct webidl_node *parent, struct webidl_node *node) +{ + struct webidl_node *child; + + child = webidl_node_getnode(parent); + if (child == NULL) { + /* parent does not have children to remove node from */ + return -1; + } + + if (child == node) { + /* parent is pointing at the node we want to remove */ + parent->r.node = node->l; /* point parent at next sibing */ + node->l = NULL; + return 0; + } + + while (child->l != NULL) { + if (child->l == node) { + /* found node, unlink from list */ + child->l = node->l; + node->l = NULL; + return 0; + } + child = child->l; + } + return -1; /* failed to remove node */ +} + +static int implements_copy_nodes(struct webidl_node *src_node, + struct webidl_node *dst_node) +{ + struct webidl_node *src; + struct webidl_node *dst; + + src = webidl_node_getnode(src_node); + dst = webidl_node_getnode(dst_node); + + while (src != NULL) { + if (src->type == WEBIDL_NODE_TYPE_LIST) { + /** @todo technicaly this should copy WEBIDL_NODE_TYPE_INTERFACE_INHERITANCE */ + dst = webidl_node_new(src->type, dst, src->r.text); + } + src = src->l; + } + + dst_node->r.node = dst; + + return 0; +} + +static int +intercalate_implements(struct webidl_node *interface_node, void *ctx) +{ + struct webidl_node *implements_node; + struct webidl_node *implements_interface_node; + struct webidl_node *webidl_ast = ctx; + + implements_node = webidl_node_find_type( + webidl_node_getnode(interface_node), + NULL, + WEBIDL_NODE_TYPE_INTERFACE_IMPLEMENTS); + while (implements_node != NULL) { + + implements_interface_node = webidl_node_find_type_ident( + webidl_ast, + WEBIDL_NODE_TYPE_INTERFACE, + webidl_node_gettext(implements_node)); + + /* recurse, ensuring all subordinate interfaces have + * their implements intercalated first + */ + intercalate_implements(implements_interface_node, webidl_ast); + + implements_copy_nodes(implements_interface_node, interface_node); + + /* once we have copied the implemntation remove entry */ + webidl_unlink(interface_node, implements_node); + + implements_node = webidl_node_find_type( + webidl_node_getnode(interface_node), + implements_node, + WEBIDL_NODE_TYPE_INTERFACE_IMPLEMENTS); + } + return 0; +} + +/* exported interface defined in webidl-ast.h */ +int webidl_intercalate_implements(struct webidl_node *webidl_ast) +{ + /* for each interface: + * for each implements entry: + * find interface from implemets + * recusrse into that interface + * copy the interface into this one + */ + return webidl_node_for_each_type(webidl_ast, + WEBIDL_NODE_TYPE_INTERFACE, + intercalate_implements, + webidl_ast); +} diff --git a/src/webidl-ast.h b/src/webidl-ast.h index eaa8d44..a494f4e 100644 --- a/src/webidl-ast.h +++ b/src/webidl-ast.h @@ -120,4 +120,7 @@ int webidl_ast_dump(struct webidl_node *node, int indent); /** parse web idl file */ int webidl_parsefile(char *filename, struct webidl_node **webidl_ast); +/** perform replacement of implements elements with copies of ast data */ +int webidl_intercalate_implements(struct webidl_node *node); + #endif |