summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorVincent Sanders <vince@kyllikki.org>2014-01-01 11:44:45 +0000
committerVincent Sanders <vince@kyllikki.org>2014-05-16 14:38:56 +0100
commited92dd097848f4628abfa3a8cc8be802a996272d (patch)
treece15362e51f5675fd4e344762af758c8aafbcc9f /src
parent12c40d1dd1bebfe92508e873cb338d419d380a03 (diff)
downloadnsgenbind-ed92dd097848f4628abfa3a8cc8be802a996272d.tar.gz
nsgenbind-ed92dd097848f4628abfa3a8cc8be802a996272d.tar.bz2
make binding constructor multiple interface capable
Diffstat (limited to 'src')
-rw-r--r--src/Makefile2
-rw-r--r--src/jsapi-libdom-init.c3
-rw-r--r--src/jsapi-libdom-new.c395
-rw-r--r--src/jsapi-libdom.c186
-rw-r--r--src/jsapi-libdom.h3
5 files changed, 401 insertions, 188 deletions
diff --git a/src/Makefile b/src/Makefile
index 8bad59a..8233398 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -1,7 +1,7 @@
CFLAGS := $(CFLAGS) -I$(BUILDDIR) -Isrc/ -g -DYYENABLE_NLS=0
# Sources in this directory
-DIR_SOURCES := nsgenbind.c webidl-ast.c nsgenbind-ast.c jsapi-libdom.c jsapi-libdom-operator.c jsapi-libdom-property.c jsapi-libdom-init.c
+DIR_SOURCES := nsgenbind.c webidl-ast.c nsgenbind-ast.c jsapi-libdom.c jsapi-libdom-operator.c jsapi-libdom-property.c jsapi-libdom-init.c jsapi-libdom-new.c
SOURCES := $(SOURCES) $(BUILDDIR)/nsgenbind-parser.c $(BUILDDIR)/nsgenbind-lexer.c $(BUILDDIR)/webidl-parser.c $(BUILDDIR)/webidl-lexer.c
diff --git a/src/jsapi-libdom-init.c b/src/jsapi-libdom-init.c
index 1f6b80d..6dfc66f 100644
--- a/src/jsapi-libdom-init.c
+++ b/src/jsapi-libdom-init.c
@@ -1,4 +1,5 @@
-/* const property generation
+/* Javascript spidemonkey API to libdom binding generation for class
+ * initilisation
*
* This file is part of nsgenbind.
* Licensed under the MIT License,
diff --git a/src/jsapi-libdom-new.c b/src/jsapi-libdom-new.c
new file mode 100644
index 0000000..b78c715
--- /dev/null
+++ b/src/jsapi-libdom-new.c
@@ -0,0 +1,395 @@
+/* Spidemonkey Javascript API to libdom binding generation for class
+ * construction.
+ *
+ * This file is part of nsgenbind.
+ * Licensed under the MIT License,
+ * http://www.opensource.org/licenses/mit-license.php
+ * Copyright 2013 Vincent Sanders <vince@netsurf-browser.org>
+ */
+
+#include <stdbool.h>
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#include "options.h"
+#include "nsgenbind-ast.h"
+#include "webidl-ast.h"
+#include "jsapi-libdom.h"
+
+static int webidl_private_param_cb(struct genbind_node *node, void *ctx)
+{
+ struct binding *binding = ctx;
+ struct genbind_node *ident_node;
+ struct genbind_node *type_node;
+
+
+ ident_node = genbind_node_find_type(genbind_node_getnode(node),
+ NULL,
+ GENBIND_NODE_TYPE_IDENT);
+ if (ident_node == NULL)
+ return -1; /* bad AST */
+
+ type_node = genbind_node_find_type(genbind_node_getnode(node),
+ NULL,
+ GENBIND_NODE_TYPE_STRING);
+ if (type_node == NULL)
+ return -1; /* bad AST */
+
+ fprintf(binding->outfile,
+ ",\n\t\t%s%s",
+ genbind_node_gettext(type_node),
+ genbind_node_gettext(ident_node));
+
+ return 0;
+}
+
+static int webidl_private_assign_cb(struct genbind_node *node, void *ctx)
+{
+ struct binding *binding = ctx;
+ struct genbind_node *ident_node;
+ const char *ident;
+
+ ident_node = genbind_node_find_type(genbind_node_getnode(node),
+ NULL,
+ GENBIND_NODE_TYPE_IDENT);
+ if (ident_node == NULL)
+ return -1; /* bad AST */
+
+ ident = genbind_node_gettext(ident_node);
+
+ fprintf(binding->outfile, "\tprivate->%s = %s;\n", ident, ident);
+
+ return 0;
+}
+
+
+
+static int
+output_binding_constructor(struct binding *binding)
+{
+ fprintf(binding->outfile,
+ "JSObject *jsapi_new_%s(JSContext *cx, \n",
+ binding->name);
+
+ fprintf(binding->outfile, "\t\tJSObject *prototype, \n");
+
+ if (binding->interfacec != 1) {
+ fprintf(binding->outfile, "\t\tconst char *interface_name, \n");
+ }
+
+ fprintf(binding->outfile, "\t\tJSObject *parent");
+
+ genbind_node_foreach_type(binding->binding_list,
+ GENBIND_NODE_TYPE_BINDING_PRIVATE,
+ webidl_private_param_cb,
+ binding);
+
+ fprintf(binding->outfile, ")");
+
+ return 0;
+}
+
+static int
+output_class_wprivate_multi(struct binding *binding)
+{
+ int inf;
+
+ /* create and initialise private data */
+ 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_foreach_type(binding->binding_list,
+ GENBIND_NODE_TYPE_BINDING_PRIVATE,
+ webidl_private_assign_cb,
+ binding);
+
+
+ fprintf(binding->outfile, "\n\n\t");
+
+ /* for each interface in the map generate initialisor */
+ for (inf = 0; inf < binding->interfacec; inf++) {
+
+ fprintf(binding->outfile,
+ "if (strcmp(interface_name, JSClass_%s.name) == 0) {\n",
+ binding->interfaces[inf].name);
+
+ fprintf(binding->outfile,
+ "\n"
+ "\t\tnewobject = JS_NewObject(cx, &JSClass_%s, prototype, parent);\n",
+ binding->interface);
+
+
+ fprintf(binding->outfile,
+ "\t\tif (newobject == NULL) {\n"
+ "\t\t\tfree(private);\n"
+ "\t\t\treturn NULL;\n"
+ "\t\t}\n\n");
+
+ /* root object to stop it being garbage collected */
+ fprintf(binding->outfile,
+ "\t\tif (JSAPI_ADD_OBJECT_ROOT(cx, &newobject) != JS_TRUE) {\n"
+ "\t\t\tfree(private);\n"
+ "\t\t\treturn NULL;\n"
+ "\t\t}\n\n");
+
+ fprintf(binding->outfile,
+ "\n"
+ "\t\t/* attach private pointer */\n"
+ "\t\tif (JS_SetPrivate(cx, newobject, private) != JS_TRUE) {\n"
+ "\t\t\tfree(private);\n"
+ "\t\t\treturn NULL;\n"
+ "\t\t}\n\n");
+
+
+ /* attach operations and attributes (functions and properties) */
+ fprintf(binding->outfile,
+ "\t\tif (JS_DefineFunctions(cx, newobject, jsclass_functions) != JS_TRUE) {\n"
+ "\t\t\tfree(private);\n"
+ "\t\t\treturn NULL;\n"
+ "\t\t}\n\n");
+
+ fprintf(binding->outfile,
+ "\t\tif (JS_DefineProperties(cx, newobject, jsclass_properties) != JS_TRUE) {\n"
+ "\t\t\tfree(private);\n"
+ "\t\t\treturn NULL;\n"
+ "\t\t}\n\n");
+
+ /* unroot object */
+ fprintf(binding->outfile,
+ "\t\tJSAPI_REMOVE_OBJECT_ROOT(cx, &newobject);\n\n"
+ "\t} else ");
+ }
+ fprintf(binding->outfile,
+ "{\n"
+ "\t\tfree(private);\n"
+ "\t\treturn NULL;\n"
+ "\t}\n");
+
+ return 0;
+}
+
+static int
+output_class_wprivate(struct binding *binding, struct genbind_node *api_node)
+{
+ /* create and initialise private data */
+ 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_foreach_type(binding->binding_list,
+ GENBIND_NODE_TYPE_BINDING_PRIVATE,
+ webidl_private_assign_cb,
+ binding);
+
+ if (api_node != NULL) {
+ output_code_block(binding, genbind_node_getnode(api_node));
+ } else {
+ fprintf(binding->outfile,
+ "\n"
+ "\tnewobject = JS_NewObject(cx, &JSClass_%s, prototype, parent);\n",
+ binding->interface);
+ }
+
+ fprintf(binding->outfile,
+ "\tif (newobject == NULL) {\n"
+ "\t\tfree(private);\n"
+ "\t\treturn NULL;\n"
+ "\t}\n\n");
+
+ /* root object to stop it being garbage collected */
+ fprintf(binding->outfile,
+ "\tif (JSAPI_ADD_OBJECT_ROOT(cx, &newobject) != JS_TRUE) {\n"
+ "\t\tfree(private);\n"
+ "\t\treturn NULL;\n"
+ "\t}\n\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");
+
+
+ /* attach operations and attributes (functions and properties) */
+ fprintf(binding->outfile,
+ "\tif (JS_DefineFunctions(cx, newobject, jsclass_functions) != JS_TRUE) {\n"
+ "\t\tfree(private);\n"
+ "\t\treturn NULL;\n"
+ "\t}\n\n");
+
+ fprintf(binding->outfile,
+ "\tif (JS_DefineProperties(cx, newobject, jsclass_properties) != JS_TRUE) {\n"
+ "\t\tfree(private);\n"
+ "\t\treturn NULL;\n"
+ "\t}\n\n");
+
+ /* unroot object */
+ fprintf(binding->outfile,
+ "\tJSAPI_REMOVE_OBJECT_ROOT(cx, &newobject);\n\n");
+
+ return 0;
+}
+
+static int
+output_class_woprivate_multi(struct binding *binding)
+{
+ int inf;
+
+ fprintf(binding->outfile, "\n\t");
+
+ /* for each interface in the map generate initialisor */
+ for (inf = 0; inf < binding->interfacec; inf++) {
+ fprintf(binding->outfile,
+ "if (strcmp(interface_name, JSClass_%s.name) == 0) {\n",
+ binding->interfaces[inf].name);
+
+ fprintf(binding->outfile,
+ "\t\tnewobject = JS_NewObject(cx, &JSClass_%s, prototype, parent);\n",
+ binding->interface);
+
+
+ fprintf(binding->outfile,
+ "\tif (newobject == NULL) {\n"
+ "\t\treturn NULL;\n"
+ "\t}\n");
+
+ /* root object to stop it being garbage collected */
+ fprintf(binding->outfile,
+ "\tif (JSAPI_ADD_OBJECT_ROOT(cx, &newobject) != JS_TRUE) {\n"
+ "\t\treturn NULL;\n"
+ "\t}\n\n");
+
+ /* attach operations and attributes (functions and properties) */
+ fprintf(binding->outfile,
+ "\tif (JS_DefineFunctions(cx, newobject, jsclass_functions) != JS_TRUE) {\n"
+ "\t\treturn NULL;\n"
+ "\t}\n\n");
+
+ fprintf(binding->outfile,
+ "\tif (JS_DefineProperties(cx, newobject, jsclass_properties) != JS_TRUE) {\n"
+ "\t\treturn NULL;\n"
+ "\t}\n\n");
+
+ /* unroot object */
+ fprintf(binding->outfile,
+ "\tJSAPI_REMOVE_OBJECT_ROOT(cx, &newobject);\n\n");
+
+ }
+ fprintf(binding->outfile,
+ "{\n"
+ "\t\tfree(private);\n"
+ "\t\treturn NULL;\n"
+ "\t}\n");
+
+
+ return 0;
+}
+
+static int
+output_class_woprivate(struct binding *binding, struct genbind_node *api_node)
+{
+
+ if (api_node != NULL) {
+ output_code_block(binding, genbind_node_getnode(api_node));
+ } else {
+ fprintf(binding->outfile,
+ "\n"
+ "\tnewobject = JS_NewObject(cx, &JSClass_%s, prototype, parent);\n",
+ binding->interface);
+
+ }
+
+ fprintf(binding->outfile,
+ "\tif (newobject == NULL) {\n"
+ "\t\treturn NULL;\n"
+ "\t}\n");
+
+ /* root object to stop it being garbage collected */
+ fprintf(binding->outfile,
+ "\tif (JSAPI_ADD_OBJECT_ROOT(cx, &newobject) != JS_TRUE) {\n"
+ "\t\treturn NULL;\n"
+ "\t}\n\n");
+
+ /* attach operations and attributes (functions and properties) */
+ fprintf(binding->outfile,
+ "\tif (JS_DefineFunctions(cx, newobject, jsclass_functions) != JS_TRUE) {\n"
+ "\t\treturn NULL;\n"
+ "\t}\n\n");
+
+ fprintf(binding->outfile,
+ "\tif (JS_DefineProperties(cx, newobject, jsclass_properties) != JS_TRUE) {\n"
+ "\t\treturn NULL;\n"
+ "\t}\n\n");
+
+ /* unroot object */
+ fprintf(binding->outfile,
+ "\tJSAPI_REMOVE_OBJECT_ROOT(cx, &newobject);\n\n");
+
+ return 0;
+}
+
+int
+output_class_new(struct binding *binding)
+{
+ int res = 0;
+ struct genbind_node *api_node;
+
+ /* constructor declaration */
+ if (binding->hdrfile) {
+ binding->outfile = binding->hdrfile;
+
+ output_binding_constructor(binding);
+
+ fprintf(binding->outfile, ";\n");
+
+ binding->outfile = binding->srcfile;
+ }
+
+ /* constructor definition */
+ output_binding_constructor(binding);
+
+ fprintf(binding->outfile,
+ "\n{\n"
+ "\tJSObject *newobject;\n");
+
+ api_node = genbind_node_find_type_ident(binding->gb_ast,
+ NULL,
+ GENBIND_NODE_TYPE_API,
+ "new");
+
+ /* generate correct constructor body */
+ if (binding->has_private) {
+ if ((binding->interfacec == 1) || (api_node != NULL)) {
+ res = output_class_wprivate(binding, api_node);
+ } else {
+ res = output_class_wprivate_multi(binding);
+ }
+ } else {
+ if ((binding->interfacec == 1) || (api_node != NULL)) {
+ res = output_class_woprivate(binding, api_node);
+ } else {
+ res = output_class_woprivate_multi(binding);
+ }
+ }
+
+ /* return newly created object */
+ fprintf(binding->outfile,
+ "\treturn newobject;\n"
+ "}\n");
+
+ return res;
+}
diff --git a/src/jsapi-libdom.c b/src/jsapi-libdom.c
index de82678..895ccf4 100644
--- a/src/jsapi-libdom.c
+++ b/src/jsapi-libdom.c
@@ -135,51 +135,7 @@ static int webidl_private_cb(struct genbind_node *node, void *ctx)
return 0;
}
-static int webidl_private_param_cb(struct genbind_node *node, void *ctx)
-{
- struct binding *binding = ctx;
- struct genbind_node *ident_node;
- struct genbind_node *type_node;
-
-
- ident_node = genbind_node_find_type(genbind_node_getnode(node),
- NULL,
- GENBIND_NODE_TYPE_IDENT);
- if (ident_node == NULL)
- return -1; /* bad AST */
-
- type_node = genbind_node_find_type(genbind_node_getnode(node),
- NULL,
- GENBIND_NODE_TYPE_STRING);
- if (type_node == NULL)
- return -1; /* bad AST */
-
- fprintf(binding->outfile,
- ",\n\t\t%s%s",
- genbind_node_gettext(type_node),
- genbind_node_gettext(ident_node));
- return 0;
-}
-
-static int webidl_private_assign_cb(struct genbind_node *node, void *ctx)
-{
- struct binding *binding = ctx;
- struct genbind_node *ident_node;
- const char *ident;
-
- ident_node = genbind_node_find_type(genbind_node_getnode(node),
- NULL,
- GENBIND_NODE_TYPE_IDENT);
- if (ident_node == NULL)
- return -1; /* bad AST */
-
- ident = genbind_node_gettext(ident_node);
-
- fprintf(binding->outfile, "\tprivate->%s = %s;\n", ident, ident);
-
- return 0;
-}
/* section output generators */
@@ -532,148 +488,6 @@ output_code_block(struct binding *binding, struct genbind_node *codelist)
}
-static int
-output_class_new(struct binding *binding)
-{
- int res = 0;
- struct genbind_node *api_node;
-
- /* constructor declaration */
- if (binding->hdrfile) {
- binding->outfile = binding->hdrfile;
-
- fprintf(binding->outfile,
- "JSObject *jsapi_new_%s(JSContext *cx,\n"
- "\t\tJSObject *prototype,\n"
- "\t\tJSObject *parent",
- binding->interface);
-
- genbind_node_foreach_type(binding->binding_list,
- GENBIND_NODE_TYPE_BINDING_PRIVATE,
- webidl_private_param_cb,
- binding);
-
- fprintf(binding->outfile, ");");
-
- binding->outfile = binding->srcfile;
- }
-
- /* constructor definition */
- fprintf(binding->outfile,
- "JSObject *jsapi_new_%s(JSContext *cx,\n"
- "\t\tJSObject *prototype,\n"
- "\t\tJSObject *parent",
- binding->interface);
-
- genbind_node_foreach_type(binding->binding_list,
- GENBIND_NODE_TYPE_BINDING_PRIVATE,
- webidl_private_param_cb,
- binding);
-
- fprintf(binding->outfile,
- ")\n"
- "{\n"
- "\tJSObject *newobject;\n");
-
- /* create private data */
- 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_foreach_type(binding->binding_list,
- GENBIND_NODE_TYPE_BINDING_PRIVATE,
- webidl_private_assign_cb,
- binding);
- }
-
- api_node = genbind_node_find_type_ident(binding->gb_ast,
- NULL,
- GENBIND_NODE_TYPE_API,
- "new");
-
- if (api_node != NULL) {
- output_code_block(binding, genbind_node_getnode(api_node));
- } else {
- fprintf(binding->outfile,
- "\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\n");
-
- /* root object to stop it being garbage collected */
- fprintf(binding->outfile,
- "\tif (JSAPI_ADD_OBJECT_ROOT(cx, &newobject) != JS_TRUE) {\n"
- "\t\tfree(private);\n"
- "\t\treturn NULL;\n"
- "\t}\n\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");
-
-
- /* attach operations and attributes (functions and properties) */
- fprintf(binding->outfile,
- "\tif (JS_DefineFunctions(cx, newobject, jsclass_functions) != JS_TRUE) {\n"
- "\t\tfree(private);\n"
- "\t\treturn NULL;\n"
- "\t}\n\n");
-
- fprintf(binding->outfile,
- "\tif (JS_DefineProperties(cx, newobject, jsclass_properties) != JS_TRUE) {\n"
- "\t\tfree(private);\n"
- "\t\treturn NULL;\n"
- "\t}\n\n");
- } else {
- fprintf(binding->outfile,
- "\tif (newobject == NULL) {\n"
- "\t\treturn NULL;\n"
- "\t}\n");
-
- /* root object to stop it being garbage collected */
- fprintf(binding->outfile,
- "\tif (JSAPI_ADD_OBJECT_ROOT(cx, &newobject) != JS_TRUE) {\n"
- "\t\treturn NULL;\n"
- "\t}\n\n");
-
- /* attach operations and attributes (functions and properties) */
- fprintf(binding->outfile,
- "\tif (JS_DefineFunctions(cx, newobject, jsclass_functions) != JS_TRUE) {\n"
- "\t\treturn NULL;\n"
- "\t}\n\n");
-
- fprintf(binding->outfile,
- "\tif (JS_DefineProperties(cx, newobject, jsclass_properties) != JS_TRUE) {\n"
- "\t\treturn NULL;\n"
- "\t}\n\n");
- }
-
- /* unroot object and return it */
- fprintf(binding->outfile,
- "\tJSAPI_REMOVE_OBJECT_ROOT(cx, &newobject);\n"
- "\n"
- "\treturn newobject;\n"
- "}\n");
-
-
- return res;
-}
static int
output_forward_declarations(struct binding *binding)
diff --git a/src/jsapi-libdom.h b/src/jsapi-libdom.h
index ee1b2f9..bdf4bec 100644
--- a/src/jsapi-libdom.h
+++ b/src/jsapi-libdom.h
@@ -90,5 +90,8 @@ int output_property_body(struct binding *binding);
/** generate binding initialisation */
int output_class_init(struct binding *binding);
+/** generate binding class constructors */
+int output_class_new(struct binding *binding);
+
#endif