summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorVincent Sanders <vince@kyllikki.org>2012-10-31 01:20:20 +0000
committerVincent Sanders <vince@kyllikki.org>2012-10-31 01:20:20 +0000
commit65e49e23019a97d51702077c82613c6c26e84033 (patch)
treef21ba90ba9dc08826ef687f9bd148e6345fd673a /src
parent26bbe37c6f0b99f23736380ba55f156f22bdaf06 (diff)
downloadnsgenbind-65e49e23019a97d51702077c82613c6c26e84033.tar.gz
nsgenbind-65e49e23019a97d51702077c82613c6c26e84033.tar.bz2
implement the "implements" webidl directive
Diffstat (limited to 'src')
-rw-r--r--src/jsapi-libdom-operator.c163
-rw-r--r--src/jsapi-libdom-property.c97
-rw-r--r--src/jsapi-libdom.c265
-rw-r--r--src/jsapi-libdom.h5
-rw-r--r--src/nsgenbind-ast.c18
-rw-r--r--src/webidl-ast.c20
-rw-r--r--src/webidl-ast.h1
-rw-r--r--src/webidl-parser.y55
8 files changed, 378 insertions, 246 deletions
diff --git a/src/jsapi-libdom-operator.c b/src/jsapi-libdom-operator.c
index 303c9da..4edf235 100644
--- a/src/jsapi-libdom-operator.c
+++ b/src/jsapi-libdom-operator.c
@@ -1,4 +1,4 @@
-/* operator body generation
+/* function/operator generation
*
* This file is part of nsgenbind.
* Licensed under the MIT License,
@@ -17,6 +17,115 @@
#include "webidl-ast.h"
#include "jsapi-libdom.h"
+static int webidl_func_spec_cb(struct webidl_node *node, void *ctx)
+{
+ struct binding *binding = ctx;
+ struct webidl_node *ident_node;
+
+ ident_node = webidl_node_find(webidl_node_getnode(node),
+ NULL,
+ webidl_cmp_node_type,
+ (void *)WEBIDL_NODE_TYPE_IDENT);
+
+ if (ident_node == NULL) {
+ /* operation without identifier - must have special keyword
+ * http://www.w3.org/TR/WebIDL/#idl-operations
+ */
+ } else {
+ fprintf(binding->outfile,
+ " JSAPI_FS(%s, 0, 0),\n",
+ webidl_node_gettext(ident_node));
+ }
+ return 0;
+}
+
+
+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)
+{
+ struct webidl_node *interface_node;
+ struct webidl_node *members_node;
+ struct webidl_node *inherit_node;
+ int res = 0;
+
+ /* find interface in webidl with correct ident attached */
+ interface_node = webidl_node_find_type_ident(binding->wi_ast,
+ WEBIDL_NODE_TYPE_INTERFACE,
+ interface);
+
+ if (interface_node == NULL) {
+ fprintf(stderr,
+ "Unable to find interface %s in loaded WebIDL\n",
+ interface);
+ return -1;
+ }
+
+ members_node = webidl_node_find(webidl_node_getnode(interface_node),
+ NULL,
+ webidl_cmp_node_type,
+ (void *)WEBIDL_NODE_TYPE_LIST);
+ while (members_node != NULL) {
+
+ fprintf(binding->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,
+ binding);
+
+ members_node = webidl_node_find(webidl_node_getnode(interface_node),
+ members_node,
+ webidl_cmp_node_type,
+ (void *)WEBIDL_NODE_TYPE_LIST);
+ }
+
+ /* check for inherited nodes and insert them too */
+ inherit_node = webidl_node_find(webidl_node_getnode(interface_node),
+ NULL,
+ webidl_cmp_node_type,
+ (void *)WEBIDL_NODE_TYPE_INTERFACE_INHERITANCE);
+
+ if (inherit_node != NULL) {
+ res = generate_function_spec(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_function_spec_implements_cb,
+ binding);
+ }
+
+ return res;
+}
+
+int output_function_spec(struct binding *binding)
+{
+ int res;
+
+ fprintf(binding->outfile,
+ "static JSFunctionSpec jsclass_functions[] = {\n");
+
+ res = generate_function_spec(binding, binding->interface);
+
+ fprintf(binding->outfile, " JSAPI_FS_END\n};\n\n");
+
+ return res;
+}
+
+
/** creates all the variable definitions
*
* generate functions variables (including return value) with default
@@ -261,7 +370,7 @@ output_operation_input(struct binding *binding,
case WEBIDL_TYPE_LONG:
/* int32_t */
fprintf(binding->outfile,
- "\tint32_t %s = 0;\n",
+ "\t%s = 0;\n",
webidl_node_gettext(arg_ident));
break;
@@ -333,23 +442,22 @@ static int webidl_operator_body_cb(struct webidl_node *node, void *ctx)
"{\n");
fprintf(binding->outfile,
- "\tstruct jsclass_private *private;\n");
-
- fprintf(binding->outfile,
"\tjsval *argv = JSAPI_ARGV(cx, vp);\n");
output_variable_definitions(binding, webidl_node_getnode(node));
- fprintf(binding->outfile,
- "\n"
- "\tprivate = JS_GetInstancePrivate(cx,\n"
- "\t\t\tJSAPI_THIS_OBJECT(cx,vp),\n"
- "\t\t\t&JSClass_%s,\n"
- "\t\t\targv);\n"
- "\tif (private == NULL)\n"
- "\t\treturn JS_FALSE;\n\n",
- binding->interface);
-
+ if (binding->has_private) {
+ fprintf(binding->outfile,
+ "\tstruct jsclass_private *private;\n"
+ "\n"
+ "\tprivate = JS_GetInstancePrivate(cx,\n"
+ "\t\t\tJSAPI_THIS_OBJECT(cx,vp),\n"
+ "\t\t\t&JSClass_%s,\n"
+ "\t\t\targv);\n"
+ "\tif (private == NULL)\n"
+ "\t\treturn JS_FALSE;\n\n",
+ binding->interface);
+ }
output_operation_input(binding, webidl_node_getnode(node));
@@ -378,7 +486,13 @@ static int webidl_operator_body_cb(struct webidl_node *node, void *ctx)
return 0;
}
+/* callback to emit implements operator bodys */
+static int webidl_implements_cb(struct webidl_node *node, void *ctx)
+{
+ struct binding *binding = ctx;
+ return output_operator_body(binding, webidl_node_gettext(node));
+}
/* exported interface documented in jsapi-libdom.h */
int
@@ -387,6 +501,7 @@ output_operator_body(struct binding *binding, const char *interface)
struct webidl_node *interface_node;
struct webidl_node *members_node;
struct webidl_node *inherit_node;
+ int res = 0;
/* find interface in webidl with correct ident attached */
interface_node = webidl_node_find_type_ident(binding->wi_ast,
@@ -421,15 +536,21 @@ output_operator_body(struct binding *binding, const char *interface)
}
/* check for inherited nodes and insert them too */
- inherit_node = webidl_node_find(webidl_node_getnode(interface_node),
+ inherit_node = webidl_node_find_type(webidl_node_getnode(interface_node),
NULL,
- webidl_cmp_node_type,
- (void *)WEBIDL_NODE_TYPE_INTERFACE_INHERITANCE);
+ WEBIDL_NODE_TYPE_INTERFACE_INHERITANCE);
if (inherit_node != NULL) {
- return output_operator_body(binding,
- webidl_node_gettext(inherit_node));
+ res = output_operator_body(binding,
+ webidl_node_gettext(inherit_node));
}
- return 0;
+ 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-property.c b/src/jsapi-libdom-property.c
index c2c6c6a..6083bb9 100644
--- a/src/jsapi-libdom-property.c
+++ b/src/jsapi-libdom-property.c
@@ -52,13 +52,22 @@ static int webidl_property_spec_cb(struct webidl_node *node, void *ctx)
return 0;
}
+static int generate_property_spec(struct binding *binding, const char *interface);
+/* 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)
{
struct webidl_node *interface_node;
struct webidl_node *members_node;
struct webidl_node *inherit_node;
-
+ int res = 0;
/* find interface in webidl with correct ident attached */
interface_node = webidl_node_find_type_ident(binding->wi_ast,
@@ -102,11 +111,18 @@ generate_property_spec(struct binding *binding, const char *interface)
(void *)WEBIDL_NODE_TYPE_INTERFACE_INHERITANCE);
if (inherit_node != NULL) {
- return generate_property_spec(binding,
+ res = generate_property_spec(binding,
webidl_node_gettext(inherit_node));
}
- return 0;
+ 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;
}
int
@@ -131,11 +147,9 @@ static int webidl_property_body_cb(struct webidl_node *node, void *ctx)
struct webidl_node *modifier_node;
struct genbind_node *property_node;
- ident_node = webidl_node_find(webidl_node_getnode(node),
- NULL,
- webidl_cmp_node_type,
- (void *)WEBIDL_NODE_TYPE_IDENT);
-
+ ident_node = webidl_node_find_type(webidl_node_getnode(node),
+ NULL,
+ WEBIDL_NODE_TYPE_IDENT);
if (ident_node == NULL) {
/* properties must have an operator
* http://www.w3.org/TR/WebIDL/#idl-attributes
@@ -143,10 +157,9 @@ static int webidl_property_body_cb(struct webidl_node *node, void *ctx)
return 1;
}
- modifier_node = webidl_node_find(webidl_node_getnode(node),
- NULL,
- webidl_cmp_node_type,
- (void *)WEBIDL_NODE_TYPE_MODIFIER);
+ modifier_node = webidl_node_find_type(webidl_node_getnode(node),
+ NULL,
+ WEBIDL_NODE_TYPE_MODIFIER);
if (webidl_node_getint(modifier_node) != WEBIDL_TYPE_READONLY) {
@@ -170,17 +183,19 @@ static int webidl_property_body_cb(struct webidl_node *node, void *ctx)
/* return value */
fprintf(binding->outfile, "\tjsval jsretval = JSVAL_NULL;\n");
- /* get context */
- fprintf(binding->outfile,
- "\tstruct jsclass_private *private;\n"
- "\n"
- "\tprivate = JS_GetInstancePrivate(cx,\n"
- "\t\tobj,\n"
- "\t\t&JSClass_%s,\n"
- "\t\tNULL);\n"
- "\tif (private == NULL)\n"
- "\t\treturn JS_FALSE;\n\n",
- binding->interface);
+ if (binding->has_private) {
+ /* get context */
+ fprintf(binding->outfile,
+ "\tstruct jsclass_private *private;\n"
+ "\n"
+ "\tprivate = JS_GetInstancePrivate(cx,\n"
+ "\t\tobj,\n"
+ "\t\t&JSClass_%s,\n"
+ "\t\tNULL);\n"
+ "\tif (private == NULL)\n"
+ "\t\treturn JS_FALSE;\n\n",
+ binding->interface);
+ }
property_node = genbind_node_find_type_ident(binding->gb_ast,
NULL,
@@ -232,6 +247,13 @@ static int webidl_property_body_cb(struct webidl_node *node, void *ctx)
return 0;
}
+/* callback to emit implements property bodys */
+static int webidl_implements_cb(struct webidl_node *node, void *ctx)
+{
+ struct binding *binding = ctx;
+
+ return output_property_body(binding, webidl_node_gettext(node));
+}
int
output_property_body(struct binding *binding, const char *interface)
@@ -239,7 +261,7 @@ output_property_body(struct binding *binding, const char *interface)
struct webidl_node *interface_node;
struct webidl_node *members_node;
struct webidl_node *inherit_node;
-
+ int res = 0;
/* find interface in webidl with correct ident attached */
interface_node = webidl_node_find_type_ident(binding->wi_ast,
@@ -253,11 +275,9 @@ output_property_body(struct binding *binding, const char *interface)
return -1;
}
- members_node = webidl_node_find(webidl_node_getnode(interface_node),
+ members_node = webidl_node_find_type(webidl_node_getnode(interface_node),
NULL,
- webidl_cmp_node_type,
- (void *)WEBIDL_NODE_TYPE_LIST);
-
+ WEBIDL_NODE_TYPE_LIST);
while (members_node != NULL) {
fprintf(binding->outfile,"/**** %s ****/\n", interface);
@@ -269,22 +289,27 @@ output_property_body(struct binding *binding, const char *interface)
binding);
- members_node = webidl_node_find(webidl_node_getnode(interface_node),
+ members_node = webidl_node_find_type(webidl_node_getnode(interface_node),
members_node,
- webidl_cmp_node_type,
- (void *)WEBIDL_NODE_TYPE_LIST);
+ WEBIDL_NODE_TYPE_LIST);
}
/* check for inherited nodes and insert them too */
- inherit_node = webidl_node_find(webidl_node_getnode(interface_node),
+ inherit_node = webidl_node_find_type(webidl_node_getnode(interface_node),
NULL,
- webidl_cmp_node_type,
- (void *)WEBIDL_NODE_TYPE_INTERFACE_INHERITANCE);
+ WEBIDL_NODE_TYPE_INTERFACE_INHERITANCE);
if (inherit_node != NULL) {
- return output_property_body(binding,
+ res = output_property_body(binding,
webidl_node_gettext(inherit_node));
}
- return 0;
+ 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 36ed6b6..5a73f5e 100644
--- a/src/jsapi-libdom.c
+++ b/src/jsapi-libdom.c
@@ -17,7 +17,7 @@
#include "webidl-ast.h"
#include "jsapi-libdom.h"
-#define HDR_COMMENT_SEP "\n * "
+#define HDR_COMMENT_SEP "\n * \n * "
#define HDR_COMMENT_PREABLE "Generated by nsgenbind "
@@ -80,85 +80,6 @@ static int webidl_hdrcomment_cb(struct genbind_node *node, void *ctx)
return 0;
}
-
-
-
-static int webidl_func_spec_cb(struct webidl_node *node, void *ctx)
-{
- struct binding *binding = ctx;
- struct webidl_node *ident_node;
-
- ident_node = webidl_node_find(webidl_node_getnode(node),
- NULL,
- webidl_cmp_node_type,
- (void *)WEBIDL_NODE_TYPE_IDENT);
-
- if (ident_node == NULL) {
- /* operation without identifier - must have special keyword
- * http://www.w3.org/TR/WebIDL/#idl-operations
- */
- } else {
- fprintf(binding->outfile,
- " JSAPI_FS(%s, 0, 0),\n",
- webidl_node_gettext(ident_node));
- }
- return 0;
-}
-
-static int
-generate_function_spec(struct binding *binding, const char *interface)
-{
- struct webidl_node *interface_node;
- 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(binding->wi_ast,
- WEBIDL_NODE_TYPE_INTERFACE,
- interface);
-
- if (interface_node == NULL) {
- fprintf(stderr,
- "Unable to find interface %s in loaded WebIDL\n",
- interface);
- return -1;
- }
-
- members_node = webidl_node_find(webidl_node_getnode(interface_node),
- NULL,
- webidl_cmp_node_type,
- (void *)WEBIDL_NODE_TYPE_LIST);
- while (members_node != NULL) {
-
- fprintf(binding->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,
- binding);
-
- members_node = webidl_node_find(webidl_node_getnode(interface_node),
- members_node,
- webidl_cmp_node_type,
- (void *)WEBIDL_NODE_TYPE_LIST);
- }
-
- /* check for inherited nodes and insert them too */
- inherit_node = webidl_node_find(webidl_node_getnode(interface_node),
- NULL,
- webidl_cmp_node_type,
- (void *)WEBIDL_NODE_TYPE_INTERFACE_INHERITANCE);
-
- if (inherit_node != NULL) {
- return generate_function_spec(binding,
- webidl_node_gettext(inherit_node));
- }
-
- return 0;
-}
-
-
static int webidl_private_cb(struct genbind_node *node, void *ctx)
{
struct binding *binding = ctx;
@@ -237,18 +158,20 @@ output_class_operations(struct binding *binding)
{
int res = 0;
- /* finalize */
- fprintf(binding->outfile,
- "static void jsclass_finalize(JSContext *cx, JSObject *obj)\n"
- "{"
- "\tstruct jsclass_private *private;\n"
- "\n"
- "\tprivate = JS_GetInstancePrivate(cx, obj, &JSClass_%s, NULL);\n"
- "\tif (private != NULL) {\n"
- "\t\tfree(private);\n"
- "\t}\n"
- "}\n\n",
- binding->interface);
+ if (binding->has_private) {
+ /* finalizer only required if there is a private to free */
+ fprintf(binding->outfile,
+ "static void jsclass_finalize(JSContext *cx, JSObject *obj)\n"
+ "{"
+ "\tstruct jsclass_private *private;\n"
+ "\n"
+ "\tprivate = JS_GetInstancePrivate(cx, obj, &JSClass_%s, NULL);\n"
+ "\tif (private != NULL) {\n"
+ "\t\tfree(private);\n"
+ "\t}\n"
+ "}\n\n",
+ binding->interface);
+ }
/* resolve */
fprintf(binding->outfile,
@@ -351,18 +274,22 @@ output_class_new(struct binding *binding)
fprintf(binding->outfile,
")\n"
"{\n"
- "\tJSObject *newobject;\n"
- "\tstruct jsclass_private *private;\n"
- "\n"
- "\tprivate = malloc(sizeof(struct jsclass_private));\n"
- "\tif (private == NULL) {\n"
- "\t\treturn NULL;\n"
- "\t}\n");
+ "\tJSObject *newobject;\n");
- genbind_node_for_each_type(genbind_node_getnode(binding_node),
- GENBIND_NODE_TYPE_BINDING_PRIVATE,
- webidl_private_assign_cb,
- binding);
+ if (binding->has_private) {
+ fprintf(binding->outfile,
+ "\tstruct jsclass_private *private;\n"
+ "\n"
+ "\tprivate = malloc(sizeof(struct jsclass_private));\n"
+ "\tif (private == NULL) {\n"
+ "\t\treturn NULL;\n"
+ "\t}\n");
+
+ genbind_node_for_each_type(genbind_node_getnode(binding_node),
+ GENBIND_NODE_TYPE_BINDING_PRIVATE,
+ webidl_private_assign_cb,
+ binding);
+ }
api_node = genbind_node_find_type_ident(binding->gb_ast,
NULL,
@@ -374,22 +301,26 @@ output_class_new(struct binding *binding)
} else {
fprintf(binding->outfile,
"\n"
- "\tnewobject = JS_NewObject(cx, &JSClass_%s, prototype, parent);\n"
+ "\tnewobject = JS_NewObject(cx, &JSClass_%s, prototype, parent);\n",
+ binding->interface);
+ }
+
+ if (binding->has_private) {
+ fprintf(binding->outfile,
"\tif (newobject == NULL) {\n"
"\t\tfree(private);\n"
"\t\treturn NULL;\n"
- "\t}\n",
- binding->interface);
+ "\t}\n"
+ "\n"
+ "\t/* attach private pointer */\n"
+ "\tif (JS_SetPrivate(cx, newobject, private) != JS_TRUE) {\n"
+ "\t\tfree(private);\n"
+ "\t\treturn NULL;\n"
+ "\t}\n");
}
fprintf(binding->outfile,
"\n"
- "\t/* attach private pointer */\n"
- "\tif (JS_SetPrivate(cx, newobject, private) != JS_TRUE) {\n"
- "\t\tfree(private);\n"
- "\t\treturn NULL;\n"
- "\t}\n"
- "\n"
"\treturn newobject;\n"
"}\n");
@@ -398,48 +329,62 @@ output_class_new(struct binding *binding)
}
-static int
-output_function_spec(struct binding *binding)
-{
- int res;
- fprintf(binding->outfile,
- "static JSFunctionSpec jsclass_functions[] = {\n");
- res = generate_function_spec(binding, binding->interface);
- fprintf(binding->outfile, " JSAPI_FS_END\n};\n\n");
+static int
+output_jsclass(struct binding *binding)
+{
+ if (binding->has_private) {
- return res;
-}
+ /* forward declare the resolver and finalizer */
+ fprintf(binding->outfile,
+ "static void jsclass_finalize(JSContext *cx, JSObject *obj);\n");
+
+ fprintf(binding->outfile,
+ "static JSBool jsclass_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags, JSObject **objp);\n\n");
+ /* output the class */
+ fprintf(binding->outfile,
+ "JSClass JSClass_%1$s = {\n"
+ " \"%1$s\",\n"
+ " JSCLASS_NEW_RESOLVE | JSCLASS_HAS_PRIVATE,\n"
+ " JS_PropertyStub,\n"
+ " JS_PropertyStub,\n"
+ " JS_PropertyStub,\n"
+ " JS_StrictPropertyStub,\n"
+ " JS_EnumerateStub,\n"
+ " (JSResolveOp)jsclass_resolve,\n"
+ " JS_ConvertStub,\n"
+ " jsclass_finalize,\n"
+ " JSCLASS_NO_OPTIONAL_MEMBERS\n"
+ "};\n\n",
+ binding->interface);
+ } else {
+ /* forward declare the resolver */
+
+ fprintf(binding->outfile,
+ "static JSBool jsclass_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags, JSObject **objp);\n\n");
-static int
-output_jsclass(struct binding *binding)
-{
- /* forward declare the resolver and finalizer */
- fprintf(binding->outfile,
- "static void jsclass_finalize(JSContext *cx, JSObject *obj);\n");
- fprintf(binding->outfile,
- "static JSBool jsclass_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags, JSObject **objp);\n\n");
- /* output the class */
- fprintf(binding->outfile,
- "JSClass JSClass_%1$s = {\n"
- " \"%1$s\",\n"
- " JSCLASS_NEW_RESOLVE | JSCLASS_HAS_PRIVATE,\n"
- " JS_PropertyStub,\n"
- " JS_PropertyStub,\n"
- " JS_PropertyStub,\n"
- " JS_StrictPropertyStub,\n"
- " JS_EnumerateStub,\n"
- " (JSResolveOp)jsclass_resolve,\n"
- " JS_ConvertStub,\n"
- " jsclass_finalize,\n"
- " JSCLASS_NO_OPTIONAL_MEMBERS\n"
- "};\n\n",
- binding->interface);
+ /* output the class */
+ fprintf(binding->outfile,
+ "JSClass JSClass_%1$s = {\n"
+ " \"%1$s\",\n"
+ " JSCLASS_NEW_RESOLVE,\n"
+ " JS_PropertyStub,\n"
+ " JS_PropertyStub,\n"
+ " JS_PropertyStub,\n"
+ " JS_StrictPropertyStub,\n"
+ " JS_EnumerateStub,\n"
+ " (JSResolveOp)jsclass_resolve,\n"
+ " JS_ConvertStub,\n"
+ " JS_FinalizeStub,\n"
+ " JSCLASS_NO_OPTIONAL_MEMBERS\n"
+ "};\n\n",
+ binding->interface);
+ }
return 0;
}
@@ -449,6 +394,10 @@ output_private_declaration(struct binding *binding)
struct genbind_node *binding_node;
struct genbind_node *type_node;
+ if (!binding->has_private) {
+ return 0;
+ }
+
binding_node = genbind_node_find(binding->gb_ast,
NULL,
genbind_cmp_node_type,
@@ -512,6 +461,28 @@ output_header_comments(struct binding *binding)
return 0;
}
+static bool
+binding_has_private(struct genbind_node *binding_node)
+{
+ struct genbind_node *node;
+
+ node = genbind_node_find_type(genbind_node_getnode(binding_node),
+ NULL,
+ GENBIND_NODE_TYPE_BINDING_PRIVATE);
+
+ if (node != NULL) {
+ return true;
+ }
+
+ node = genbind_node_find_type(genbind_node_getnode(binding_node),
+ NULL,
+ GENBIND_NODE_TYPE_BINDING_INTERNAL);
+ if (node != NULL) {
+ return true;
+ }
+ return false;
+}
+
static struct binding *
binding_new(char *outfilename, struct genbind_node *genbind_ast)
{
@@ -571,7 +542,7 @@ binding_new(char *outfilename, struct genbind_node *genbind_ast)
nb->name = genbind_node_gettext(ident_node);
nb->interface = genbind_node_gettext(interface_node);
nb->outfile = outfile;
-
+ nb->has_private = binding_has_private(binding_node);
return nb;
}
diff --git a/src/jsapi-libdom.h b/src/jsapi-libdom.h
index f318b5d..a5db6ec 100644
--- a/src/jsapi-libdom.h
+++ b/src/jsapi-libdom.h
@@ -12,8 +12,12 @@
struct binding {
struct genbind_node *gb_ast;
struct webidl_node *wi_ast;
+
const char *name; /* name of the binding */
const char *interface; /* webidl interface binding is for */
+
+ bool has_private; /* true if the binding requires a private structure */
+
FILE *outfile ; /* output file */
};
@@ -36,6 +40,7 @@ void output_code_block(struct binding *binding, struct genbind_node *codelist);
* @param interface The interface to generate operator bodys for
*/
int output_operator_body(struct binding *binding, const char *interface);
+int output_function_spec(struct binding *binding);
int output_property_spec(struct binding *binding);
int output_property_body(struct binding *binding, const char *interface);
diff --git a/src/nsgenbind-ast.c b/src/nsgenbind-ast.c
index e633439..c14f0df 100644
--- a/src/nsgenbind-ast.c
+++ b/src/nsgenbind-ast.c
@@ -100,7 +100,7 @@ genbind_node_find(struct genbind_node *node,
{
struct genbind_node *ret;
- if (node == NULL) {
+ if ((node == NULL) || (node == prev)) {
return NULL;
}
@@ -139,27 +139,21 @@ genbind_node_find_type_ident(struct genbind_node *node,
struct genbind_node *found_node;
struct genbind_node *ident_node;
- found_node = genbind_node_find(node,
- prev,
- genbind_cmp_node_type,
- (void *)type);
+ found_node = genbind_node_find_type(node, prev, type);
+
while (found_node != NULL) {
- ident_node = genbind_node_find(genbind_node_getnode(found_node),
+ ident_node = genbind_node_find_type(genbind_node_getnode(found_node),
NULL,
- genbind_cmp_node_type,
- (void *)GENBIND_NODE_TYPE_IDENT);
+ GENBIND_NODE_TYPE_IDENT);
if (ident_node != NULL) {
if (strcmp(ident_node->r.text, ident) == 0)
break;
}
/* look for next matching node */
- found_node = genbind_node_find(node,
- found_node,
- genbind_cmp_node_type,
- (void *)type);
+ found_node = genbind_node_find_type(node, found_node, type);
}
return found_node;
diff --git a/src/webidl-ast.c b/src/webidl-ast.c
index fef5f35..a1f2276 100644
--- a/src/webidl-ast.c
+++ b/src/webidl-ast.c
@@ -193,26 +193,19 @@ webidl_node_find_type_ident(struct webidl_node *root_node,
struct webidl_node *node;
struct webidl_node *ident_node;
- node = webidl_node_find(root_node,
- NULL,
- webidl_cmp_node_type,
- (void *)type);
+ node = webidl_node_find_type(root_node, NULL, type);
while (node != NULL) {
- ident_node = webidl_node_find(webidl_node_getnode(node),
+ ident_node = webidl_node_find_type(webidl_node_getnode(node),
NULL,
- webidl_cmp_node_type,
- (void *)WEBIDL_NODE_TYPE_IDENT);
+ WEBIDL_NODE_TYPE_IDENT);
if (ident_node != NULL) {
if (strcmp(ident_node->r.text, ident) == 0)
break;
}
- node = webidl_node_find(root_node,
- node,
- webidl_cmp_node_type,
- (void *)type);
+ node = webidl_node_find_type(root_node, node, type);
}
return node;
@@ -224,7 +217,7 @@ char *webidl_node_gettext(struct webidl_node *node)
switch(node->type) {
case WEBIDL_NODE_TYPE_IDENT:
case WEBIDL_NODE_TYPE_INTERFACE_INHERITANCE:
-
+ case WEBIDL_NODE_TYPE_INTERFACE_IMPLEMENTS:
return node->r.text;
default:
@@ -289,6 +282,9 @@ static const char *webidl_node_type_to_str(enum webidl_node_type type)
case WEBIDL_NODE_TYPE_INTERFACE_INHERITANCE:
return "Inherit";
+ case WEBIDL_NODE_TYPE_INTERFACE_IMPLEMENTS:
+ return "Implements";
+
case WEBIDL_NODE_TYPE_INTERFACE:
return "Interface";
diff --git a/src/webidl-ast.h b/src/webidl-ast.h
index 2117cfa..d891dec 100644
--- a/src/webidl-ast.h
+++ b/src/webidl-ast.h
@@ -21,6 +21,7 @@ enum webidl_node_type {
/* non structural node types */
WEBIDL_NODE_TYPE_INTERFACE,
WEBIDL_NODE_TYPE_INTERFACE_INHERITANCE,
+ WEBIDL_NODE_TYPE_INTERFACE_IMPLEMENTS,
WEBIDL_NODE_TYPE_ATTRIBUTE,
WEBIDL_NODE_TYPE_OPERATION,
WEBIDL_NODE_TYPE_CONST,
diff --git a/src/webidl-parser.y b/src/webidl-parser.y
index 3cf1b6c..53e21e1 100644
--- a/src/webidl-parser.y
+++ b/src/webidl-parser.y
@@ -167,22 +167,9 @@ webidl_error(YYLTYPE *locp, struct webidl_node **winbind_ast, const char *str)
%%
- /* default rule to add built AST to passed in one */
-Input:
- Definitions
- {
- *webidl_ast = webidl_node_prepend(*webidl_ast, $1);
- }
- |
- error
- {
- fprintf(stderr, "%d: %s\n", yylloc.first_line, errtxt);
- free(errtxt);
- YYABORT ;
- }
- ;
-
- /* [1] altered from original grammar to be left recusive, */
+ /* [1] default rule to add built AST to passed in one, altered from
+ * original grammar to be left recusive,
+ */
Definitions:
/* empty */
{
@@ -191,7 +178,14 @@ Definitions:
|
Definitions ExtendedAttributeList Definition
{
- $$ = webidl_node_prepend($1, $3);
+ $$ = *webidl_ast = webidl_node_prepend(*webidl_ast, $3);
+ }
+ |
+ error
+ {
+ fprintf(stderr, "%d: %s\n", yylloc.first_line, errtxt);
+ free(errtxt);
+ YYABORT ;
}
;
@@ -248,6 +242,7 @@ Interface:
interface_node = webidl_node_find_type_ident(*webidl_ast,
WEBIDL_NODE_TYPE_INTERFACE,
$2);
+
if (interface_node == NULL) {
/* no existing interface - create one with ident */
members = webidl_node_new(WEBIDL_NODE_TYPE_IDENT, members, $2);
@@ -480,7 +475,31 @@ Typedef:
ImplementsStatement:
TOK_IDENTIFIER TOK_IMPLEMENTS TOK_IDENTIFIER ';'
{
- $$ = NULL;
+ /* extend interface with implements members */
+ struct webidl_node *implements;
+ struct webidl_node *interface_node;
+
+
+ interface_node = webidl_node_find_type_ident(*webidl_ast,
+ WEBIDL_NODE_TYPE_INTERFACE,
+ $1);
+
+ implements = webidl_node_new(WEBIDL_NODE_TYPE_INTERFACE_IMPLEMENTS, NULL, $3);
+
+ if (interface_node == NULL) {
+ /* interface doesnt already exist so create it */
+
+ implements = webidl_node_new(WEBIDL_NODE_TYPE_IDENT, implements, $1);
+
+ $$ = webidl_node_new(WEBIDL_NODE_TYPE_INTERFACE, NULL, implements);
+ } else {
+ /* update the existing interface */
+
+ /* link implements node into interfaces_node */
+ webidl_node_add(interface_node, implements);
+
+ $$ = NULL; /* updating so no need to add a new node */
+ }
}
;