diff options
author | Vincent Sanders <vince@kyllikki.org> | 2012-10-31 01:20:20 +0000 |
---|---|---|
committer | Vincent Sanders <vince@kyllikki.org> | 2012-10-31 01:20:20 +0000 |
commit | 65e49e23019a97d51702077c82613c6c26e84033 (patch) | |
tree | f21ba90ba9dc08826ef687f9bd148e6345fd673a /src/jsapi-libdom.c | |
parent | 26bbe37c6f0b99f23736380ba55f156f22bdaf06 (diff) | |
download | nsgenbind-65e49e23019a97d51702077c82613c6c26e84033.tar.gz nsgenbind-65e49e23019a97d51702077c82613c6c26e84033.tar.bz2 |
implement the "implements" webidl directive
Diffstat (limited to 'src/jsapi-libdom.c')
-rw-r--r-- | src/jsapi-libdom.c | 265 |
1 files changed, 118 insertions, 147 deletions
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; } |