diff options
-rw-r--r-- | src/Makefile | 2 | ||||
-rw-r--r-- | src/jsapi-libdom-operator.c | 184 | ||||
-rw-r--r-- | src/jsapi-libdom.c | 125 | ||||
-rw-r--r-- | src/jsapi-libdom.h | 26 | ||||
-rw-r--r-- | test/data/bindings/htmldocument.bnd | 5 |
5 files changed, 213 insertions, 129 deletions
diff --git a/src/Makefile b/src/Makefile index 530dd4b..c4821bf 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,7 +1,7 @@ CFLAGS := $(CFLAGS) -I$(BUILDDIR) -Isrc/ -g # Sources in this directory -DIR_SOURCES := genjsbind.c webidl-ast.c genjsbind-ast.c jsapi-libdom.c +DIR_SOURCES := genjsbind.c webidl-ast.c genjsbind-ast.c jsapi-libdom.c jsapi-libdom-operator.c SOURCES := $(SOURCES) $(BUILDDIR)/genjsbind-parser.c $(BUILDDIR)/genjsbind-lexer.c $(BUILDDIR)/webidl-parser.c $(BUILDDIR)/webidl-lexer.c diff --git a/src/jsapi-libdom-operator.c b/src/jsapi-libdom-operator.c new file mode 100644 index 0000000..64a5059 --- /dev/null +++ b/src/jsapi-libdom-operator.c @@ -0,0 +1,184 @@ +/* operator body generation + * + * This file is part of nsgenjsbind. + * Licensed under the MIT License, + * http://www.opensource.org/licenses/mit-license.php + * Copyright 2012 Vincent Sanders <vince@netsurf-browser.org> + */ + +#include <stdbool.h> +#include <stdio.h> +#include <errno.h> +#include <string.h> +#include <stdlib.h> + +#include "options.h" +#include "genjsbind-ast.h" +#include "webidl-ast.h" +#include "jsapi-libdom.h" + +static void +define_ret_value(struct binding *binding, struct webidl_node *operator_list) +{ + operator_list = operator_list; + fprintf(binding->outfile, "\tjsval jsretval = JSVAL_VOID;\n"); +} + +static void +output_operation_input(struct binding *binding, + struct webidl_node *operation_list) +{ +/* + if (!JS_ConvertArguments(cx, argc, JSAPI_ARGV(cx, vp), "S", &u16_txt)) { + return JS_FALSE; + } + + JSString_to_char(u16_txt, txt, length); + +*/ + + struct webidl_node *arglist; + + arglist = webidl_node_find(operation_list, + NULL, + webidl_cmp_node_type, + (void *)WEBIDL_NODE_TYPE_LIST); + + arglist = webidl_node_getnode(arglist); + +} + +static void +output_operation_code_block(struct binding *binding, + struct genbind_node *operation_list) +{ + struct genbind_node *code_node; + + code_node = genbind_node_find_type(operation_list, + NULL, + GENBIND_NODE_TYPE_CBLOCK); + if (code_node != NULL) { + fprintf(binding->outfile, + "%s\n", + genbind_node_gettext(code_node)); + } +} + + +static int webidl_operator_body_cb(struct webidl_node *node, void *ctx) +{ + struct binding *binding = ctx; + struct webidl_node *ident_node; + struct genbind_node *operation_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 { + /* normal operation with identifier */ + + fprintf(binding->outfile, + "static JSBool JSAPI_NATIVE(%s, JSContext *cx, uintN argc, jsval *vp)\n", + webidl_node_gettext(ident_node)); + fprintf(binding->outfile, + "{\n"); + + fprintf(binding->outfile, + "\tstruct jsclass_private *private;\n"); + + /* creates the return value variable with a default value */ + define_ret_value(binding, webidl_node_getnode(node)); + + fprintf(binding->outfile, + "\n" + "\tprivate = JS_GetInstancePrivate(cx,\n" + "\t\t\tJS_THIS_OBJECT(cx,vp),\n" + "\t\t\t&jsclass_object,\n" + "\t\t\tNULL);\n" + "\tif (priv == NULL)\n" + "\t\treturn JS_FALSE;\n"); + + + output_operation_input(binding, webidl_node_getnode(node)); + + operation_node = genbind_node_find_type_ident(binding->gb_ast, + NULL, + GENBIND_NODE_TYPE_OPERATION, + webidl_node_gettext(ident_node)); + + if (operation_node != NULL) { + output_operation_code_block(binding, + genbind_node_getnode(operation_node)); + + } + + /* set return value an return true */ + fprintf(binding->outfile, + "\tJSAPI_SET_RVAL(cx, vp, jsretval);\n" + "\treturn JS_TRUE;\n" + "}\n\n"); + } + return 0; +} + + + +/* exported interface documented in jsapi-libdom.h */ +int +output_operator_body(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_operator_body_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 output_operator_body(binding, + webidl_node_gettext(inherit_node)); + } + + return 0; +} diff --git a/src/jsapi-libdom.c b/src/jsapi-libdom.c index f5b9ed5..adb0b5e 100644 --- a/src/jsapi-libdom.c +++ b/src/jsapi-libdom.c @@ -20,13 +20,6 @@ #define HDR_COMMENT_SEP "\n * " #define HDR_COMMENT_PREABLE "Generated by nsgenjsapi" -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 */ - FILE *outfile ; /* output file */ -}; static int webidl_file_cb(struct genbind_node *node, void *ctx) { @@ -259,70 +252,6 @@ generate_function_spec(struct binding *binding, const char *interface) -static int webidl_function_body_cb(struct webidl_node *node, void *ctx) -{ - struct binding *binding = ctx; - struct webidl_node *ident_node; - struct genbind_node *operation_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 { - /* normal operation with identifier */ - - fprintf(binding->outfile, - "static JSBool JSAPI_NATIVE(%s, JSContext *cx, uintN argc, jsval *vp)\n", - webidl_node_gettext(ident_node)); - fprintf(binding->outfile, - "{\n"); - - fprintf(binding->outfile, - " struct jsclass_private *private;\n"); - - fprintf(binding->outfile, - " private = JS_GetInstancePrivate(cx,\n" - " JS_THIS_OBJECT(cx,vp),\n" - " &jsclass_object,\n" - " NULL);\n" - " if (priv == NULL)\n" - " return JS_FALSE;\n"); - -/* - - JSAPI_SET_RVAL(cx, vp, JSVAL_VOID); -*/ - - operation_node = genbind_node_find_type_ident(binding->gb_ast, - NULL, - GENBIND_NODE_TYPE_OPERATION, - webidl_node_gettext(ident_node)); - - if (operation_node != NULL) { - struct genbind_node *code_node; - - code_node = genbind_node_find_type(genbind_node_getnode(operation_node), - NULL, - GENBIND_NODE_TYPE_CBLOCK); - if (code_node != NULL) { - fprintf(binding->outfile, - "%s\n", - genbind_node_gettext(code_node)); - } - } - - - fprintf(binding->outfile, "}\n\n"); - - } - return 0; -} @@ -486,58 +415,6 @@ output_property_body(struct binding *binding, const char *interface) return 0; } -static int -output_function_body(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_function_body_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 output_function_body(binding, - webidl_node_gettext(inherit_node)); - } - - return 0; -} static int output_jsclass(struct binding *binding) @@ -722,7 +599,7 @@ int jsapi_libdom_output(char *outfilename, struct genbind_node *genbind_ast) return 8; } - res = output_function_body(binding, binding->interface); + res = output_operator_body(binding, binding->interface); if (res) { return 9; } diff --git a/src/jsapi-libdom.h b/src/jsapi-libdom.h index fe28723..e199ec7 100644 --- a/src/jsapi-libdom.h +++ b/src/jsapi-libdom.h @@ -9,6 +9,32 @@ #ifndef genjsbind_jsapi_libdom_h #define genjsbind_jsapi_libdom_h +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 */ + FILE *outfile ; /* output file */ +}; + +/* Generate jsapi native function bodys + * + * web IDL describes methods as operators + * http://www.w3.org/TR/WebIDL/#idl-operations + * + * This walks the web IDL AST to find all operator interface members + * and construct appropriate jsapi native function body to implement + * them. + * + * Function body contents can be overriden with an operator code + * block in the binding definition. + * + * @param binding The binding information + * @param interface The interface to generate operator bodys for + */ +int output_operator_body(struct binding *binding, const char *interface); + +/** Generate binding between jsapi and netsurf libdom */ int jsapi_libdom_output(char *outfile, struct genbind_node *genbind_root); #endif diff --git a/test/data/bindings/htmldocument.bnd b/test/data/bindings/htmldocument.bnd index 8d35df9..9b47433 100644 --- a/test/data/bindings/htmldocument.bnd +++ b/test/data/bindings/htmldocument.bnd @@ -37,10 +37,7 @@ operation write %{ if (document->htmlc->parser != NULL) { dom_hubbub_parser_insert_chunk(document->htmlc->parser, (uint8_t *)txt, length); } - JSAPI_SET_RVAL(cx, vp, JSVAL_VOID); - - return JS_TRUE; - %} +%} binding document { type js_libdom; /* the binding type */ |