summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/jsapi-libdom-function.c24
-rw-r--r--src/jsapi-libdom-property.c47
-rw-r--r--src/jsapi-libdom.c4
-rw-r--r--src/webidl-ast.c125
-rw-r--r--src/webidl-ast.h3
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