summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README24
-rw-r--r--src/Makefile2
-rw-r--r--src/interface-map.c292
-rw-r--r--src/interface-map.h43
-rw-r--r--src/jsapi-libdom-infmap.c348
-rw-r--r--src/nsgenbind-ast.h2
-rw-r--r--src/nsgenbind.c13
-rw-r--r--test/data/bindings/browser-duk.bnd1
-rw-r--r--test/data/idl/uievents.idl185
9 files changed, 559 insertions, 351 deletions
diff --git a/README b/README
index e260642..039bd6a 100644
--- a/README
+++ b/README
@@ -37,6 +37,30 @@ The tool requires a binding file as input and an output directory in
which to place its output.
+Debug output
+------------
+
+as well as the generated source the tool will output seevral debugging
+files with the -D switch in use.
+
+interface.dot
+
+ The interfaces IDL dot file contains all the interfaces and their
+ relationship. graphviz can be used to convert this into a visual
+ representation which is sometimes useful to help in debugging
+ missing or incorrect IDL inheritance.
+
+ Processing the dot file with graphviz can produce very large files
+ so care must be taken with options. Some examples that produce
+ adequate output:
+
+ # classical tree
+ dot -O -Tsvg interface.dot
+
+ # radial output
+ twopi -Granksep=10.0 -Gnodesep=1.0 -Groot=0009 -O -Tsvg interface.dot
+
+
Web IDL
-------
diff --git a/src/Makefile b/src/Makefile
index 3e5b8af..b7b142a 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 utils.c webidl-ast.c nsgenbind-ast.c
+DIR_SOURCES := nsgenbind.c utils.c webidl-ast.c nsgenbind-ast.c interface-map.c
# jsapi-libdom.c jsapi-libdom-function.c jsapi-libdom-property.c jsapi-libdom-init.c jsapi-libdom-new.c jsapi-libdom-infmap.c jsapi-libdom-jsclass.c
SOURCES := $(SOURCES) $(BUILDDIR)/nsgenbind-parser.c $(BUILDDIR)/nsgenbind-lexer.c $(BUILDDIR)/webidl-parser.c $(BUILDDIR)/webidl-lexer.c
diff --git a/src/interface-map.c b/src/interface-map.c
new file mode 100644
index 0000000..aef697e
--- /dev/null
+++ b/src/interface-map.c
@@ -0,0 +1,292 @@
+/* interface mapping
+ *
+ * This file is part of nsgenbind.
+ * Published under the MIT License,
+ * http://www.opensource.org/licenses/mit-license.php
+ * Copyright 2015 Vincent Sanders <vince@netsurf-browser.org>
+ */
+
+#include <stdbool.h>
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#include "options.h"
+#include "utils.h"
+#include "nsgenbind-ast.h"
+#include "webidl-ast.h"
+#include "interface-map.h"
+
+/** count the number of nodes of a given type on an interface */
+static int
+enumerate_interface_type(struct webidl_node *interface_node,
+ enum webidl_node_type node_type)
+{
+ int count = 0;
+ struct webidl_node *members_node;
+
+ members_node = webidl_node_find_type(
+ webidl_node_getnode(interface_node),
+ NULL,
+ WEBIDL_NODE_TYPE_LIST);
+ while (members_node != NULL) {
+ count += webidl_node_enumerate_type(
+ webidl_node_getnode(members_node),
+ node_type);
+
+ members_node = webidl_node_find_type(
+ webidl_node_getnode(interface_node),
+ members_node,
+ WEBIDL_NODE_TYPE_LIST);
+ }
+
+ return count;
+}
+
+/* find index of inherited node if it is one of those listed in the
+ * binding also maintain refcounts
+ */
+static void
+compute_inherit_refcount(struct interface_map_entry *entries, int entryc)
+{
+ int idx;
+ int inf;
+
+ for (idx = 0; idx < entryc; idx++ ) {
+ entries[idx].inherit_idx = -1;
+ for (inf = 0; inf < entryc; inf++ ) {
+ /* cannot inherit from self and name must match */
+ if ((inf != idx) &&
+ (entries[idx].inherit_name != NULL ) &&
+ (strcmp(entries[idx].inherit_name,
+ entries[inf].name) == 0)) {
+ entries[idx].inherit_idx = inf;
+ entries[inf].refcount++;
+ break;
+ }
+ }
+ }
+}
+
+/** Topoligical sort based on the refcount
+ *
+ * do not need to consider loops as constructed graph is a acyclic
+ *
+ * alloc a second copy of the map
+ * repeat until all entries copied:
+ * walk source mapping until first entry with zero refcount
+ * put the entry at the end of the output map
+ * reduce refcount on inherit index if !=-1
+ * remove entry from source map
+ */
+static struct interface_map_entry *
+interface_topoligical_sort(struct interface_map_entry *srcinf, int infc)
+{
+ struct interface_map_entry *dstinf;
+ int idx;
+ int inf;
+
+ dstinf = calloc(infc, sizeof(struct interface_map_entry));
+ if (dstinf == NULL) {
+ return NULL;
+ }
+
+ for (idx = infc - 1; idx >= 0; idx--) {
+ /* walk source map until first valid entry with zero refcount */
+ inf = 0;
+ while ((inf < infc) &&
+ ((srcinf[inf].name == NULL) ||
+ (srcinf[inf].refcount > 0))) {
+ inf++;
+ }
+ if (inf == infc) {
+ free(dstinf);
+ return NULL;
+ }
+
+ /* copy entry to the end of the output map */
+ dstinf[idx].name = srcinf[inf].name;
+ dstinf[idx].node = srcinf[inf].node;
+ dstinf[idx].inherit_name = srcinf[inf].inherit_name;
+ dstinf[idx].operations = srcinf[inf].operations;
+ dstinf[idx].attributes = srcinf[inf].attributes;
+ dstinf[idx].class = srcinf[inf].class;
+
+ /* reduce refcount on inherit index if !=-1 */
+ if (srcinf[inf].inherit_idx != -1) {
+ srcinf[srcinf[inf].inherit_idx].refcount--;
+ }
+
+ /* remove entry from source map */
+ srcinf[inf].name = NULL;
+ }
+
+ return dstinf;
+}
+
+int interface_map_new(struct genbind_node *genbind,
+ struct webidl_node *webidl,
+ struct interface_map **index_out)
+{
+ int interfacec;
+ struct interface_map_entry *entries;
+ struct interface_map_entry *sorted_entries;
+ struct interface_map_entry *ecur;
+ struct webidl_node *node;
+ struct interface_map *index;
+
+ interfacec = webidl_node_enumerate_type(webidl,
+ WEBIDL_NODE_TYPE_INTERFACE);
+
+ if (options->verbose) {
+ printf("Indexing %d interfaces\n", interfacec);
+ }
+
+ entries = calloc(interfacec, sizeof(struct interface_map_entry));
+ if (entries == NULL) {
+ return -1;
+ }
+
+ /* for each interface populate an entry in the index */
+ ecur = entries;
+ node = webidl_node_find_type(webidl, NULL, WEBIDL_NODE_TYPE_INTERFACE);
+ while (node != NULL) {
+
+ /* fill index entry */
+ ecur->node = node;
+
+ /* name of interface */
+ ecur->name = webidl_node_gettext(
+ webidl_node_find_type(
+ webidl_node_getnode(node),
+ NULL,
+ GENBIND_NODE_TYPE_IDENT));
+
+ /* name of the inherited interface (if any) */
+ ecur->inherit_name = webidl_node_gettext(
+ webidl_node_find_type(
+ webidl_node_getnode(node),
+ NULL,
+ WEBIDL_NODE_TYPE_INTERFACE_INHERITANCE));
+
+
+ /* enumerate the number of operations */
+ ecur->operations = enumerate_interface_type(node,
+ WEBIDL_NODE_TYPE_OPERATION);
+
+ /* enumerate the number of attributes */
+ ecur->attributes = enumerate_interface_type(node,
+ WEBIDL_NODE_TYPE_ATTRIBUTE);
+
+
+ /* matching class from binding */
+ ecur->class = genbind_node_find_type_ident(genbind,
+ NULL, GENBIND_NODE_TYPE_CLASS, ecur->name);
+
+ /* move to next interface */
+ node = webidl_node_find_type(webidl, node,
+ WEBIDL_NODE_TYPE_INTERFACE);
+ ecur++;
+ }
+
+ /* compute inheritance and refcounts on map */
+ compute_inherit_refcount(entries, interfacec);
+
+ /* sort interfaces to ensure correct ordering */
+ sorted_entries = interface_topoligical_sort(entries, interfacec);
+ free(entries);
+ if (sorted_entries == NULL) {
+ return -1;
+ }
+
+ /* compute inheritance and refcounts on sorted map */
+ compute_inherit_refcount(sorted_entries, interfacec);
+
+ index = malloc(sizeof(struct interface_map));
+ index->entryc = interfacec;
+ index->entries = sorted_entries;
+
+ *index_out = index;
+
+ return 0;
+}
+
+int interface_map_dump(struct interface_map *index)
+{
+ FILE *dumpf;
+ int eidx;
+ struct interface_map_entry *ecur;
+ const char *inherit_name;
+
+ /* only dump AST to file if required */
+ if (!options->debug) {
+ return 0;
+ }
+
+ dumpf = genb_fopen("interface-index", "w");
+ if (dumpf == NULL) {
+ return 2;
+ }
+
+ ecur = index->entries;
+ for (eidx = 0; eidx < index->entryc; eidx++) {
+ inherit_name = ecur->inherit_name;
+ if (inherit_name == NULL) {
+ inherit_name = "";
+ }
+ fprintf(dumpf, "%d %s %s i:%d a:%d %p\n", eidx, ecur->name,
+ inherit_name, ecur->operations, ecur->attributes,
+ ecur->class);
+ ecur++;
+ }
+
+ fclose(dumpf);
+
+ return 0;
+}
+
+int interface_map_dumpdot(struct interface_map *index)
+{
+ FILE *dumpf;
+ int eidx;
+ struct interface_map_entry *ecur;
+
+ /* only dump AST to file if required */
+ if (!options->debug) {
+ return 0;
+ }
+
+ dumpf = genb_fopen("interface.dot", "w");
+ if (dumpf == NULL) {
+ return 2;
+ }
+
+ fprintf(dumpf, "digraph interfaces {\n");
+
+ ecur = index->entries;
+ for (eidx = 0; eidx < index->entryc; eidx++) {
+ if (ecur->class != NULL) {
+ /* interfaces bound to a class are shown in blue */
+ fprintf(dumpf, "%04d [label=\"%s\" fontcolor=\"blue\"];\n", eidx, ecur->name);
+ } else {
+ fprintf(dumpf, "%04d [label=\"%s\"];\n", eidx, ecur->name);
+ }
+ ecur++;
+ }
+
+ ecur = index->entries;
+ for (eidx = 0; eidx < index->entryc; eidx++) {
+ if (index->entries[eidx].inherit_idx != -1) {
+ fprintf(dumpf, "%04d -> %04d;\n",
+ eidx, index->entries[eidx].inherit_idx);
+ }
+ }
+
+ fprintf(dumpf, "}\n");
+
+ fclose(dumpf);
+
+ return 0;
+}
diff --git a/src/interface-map.h b/src/interface-map.h
new file mode 100644
index 0000000..c9dd654
--- /dev/null
+++ b/src/interface-map.h
@@ -0,0 +1,43 @@
+/* Interface mapping
+ *
+ * This file is part of nsgenbind.
+ * Licensed under the MIT License,
+ * http://www.opensource.org/licenses/mit-license.php
+ * Copyright 2012 Vincent Sanders <vince@netsurf-browser.org>
+ */
+
+#ifndef nsgenbind_interface_map_h
+#define nsgenbind_interface_map_h
+
+struct genbind_node;
+struct webidl_node;
+
+struct interface_map_entry {
+ const char *name; /** interface name */
+ struct webidl_node *node; /**< AST interface node */
+ const char *inherit_name; /**< Name of interface inhertited from */
+ int operations; /**< number of operations on interface */
+ int attributes; /**< number of attributes on interface */
+ int inherit_idx; /**< index into map of inherited interface or -1 for
+ * not in map
+ */
+ int refcount; /**< number of interfacess in map that refer to this
+ * interface
+ */
+ struct genbind_node *class; /**< class from binding (if any) */
+};
+
+struct interface_map {
+ int entryc; /**< count of interfaces */
+ struct interface_map_entry *entries;
+};
+
+int interface_map_new(struct genbind_node *genbind,
+ struct webidl_node *webidl,
+ struct interface_map **index_out);
+
+int interface_map_dump(struct interface_map *index);
+
+int interface_map_dumpdot(struct interface_map *index);
+
+#endif
diff --git a/src/jsapi-libdom-infmap.c b/src/jsapi-libdom-infmap.c
deleted file mode 100644
index 09fce1e..0000000
--- a/src/jsapi-libdom-infmap.c
+++ /dev/null
@@ -1,348 +0,0 @@
-/* interface map builder
- *
- * This file is part of nsgenbind.
- * Published under the MIT License,
- * http://www.opensource.org/licenses/mit-license.php
- * Copyright 2014 Vincent Sanders <vince@netsurf-browser.org>
- */
-
-#include <stdbool.h>
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
-#include <stdlib.h>
-#include <ctype.h>
-
-#include "options.h"
-#include "nsgenbind-ast.h"
-#include "webidl-ast.h"
-#include "jsapi-libdom.h"
-
-/** count the number of methods or properties for an interface */
-static int
-enumerate_interface_own(struct webidl_node *interface_node,
- enum webidl_node_type node_type)
-{
- int count = 0;
- struct webidl_node *members_node;
-
- members_node = webidl_node_find_type(
- webidl_node_getnode(interface_node),
- NULL,
- WEBIDL_NODE_TYPE_LIST);
- while (members_node != NULL) {
- count += webidl_node_enumerate_type(
- webidl_node_getnode(members_node),
- node_type);
-
- members_node = webidl_node_find_type(
- webidl_node_getnode(interface_node),
- members_node,
- WEBIDL_NODE_TYPE_LIST);
- }
-
- return count;
-}
-
-static int
-fill_binding_interface(struct webidl_node *webidl_ast,
- struct binding_interface *interface)
-{
- /* get web IDL node for interface */
- interface->widl_node = webidl_node_find_type_ident(
- webidl_ast,
- WEBIDL_NODE_TYPE_INTERFACE,
- interface->name);
- if (interface->widl_node == NULL) {
- return -1;
- }
-
- /* enumerate the number of functions */
- interface->own_functions = enumerate_interface_own(
- interface->widl_node,
- WEBIDL_NODE_TYPE_OPERATION);
-
- /* enumerate the number of properties */
- interface->own_properties = enumerate_interface_own(
- interface->widl_node,
- WEBIDL_NODE_TYPE_ATTRIBUTE);
-
- /* extract the name of the inherited interface (if any) */
- interface->inherit_name = webidl_node_gettext(
- webidl_node_find_type(
- webidl_node_getnode(interface->widl_node),
- NULL,
- WEBIDL_NODE_TYPE_INTERFACE_INHERITANCE));
-
- return 0;
-}
-
-/* find index of inherited node if it is one of those listed in the
- * binding also maintain refcounts
- */
-static void
-compute_inherit_refcount(struct binding_interface *interfaces,
- int interfacec)
-{
- int idx;
- int inf;
-
- for (idx = 0; idx < interfacec; idx++ ) {
- interfaces[idx].inherit_idx = -1;
- for (inf = 0; inf < interfacec; inf++ ) {
- /* cannot inherit from self and name must match */
- if ((inf != idx) &&
- (interfaces[idx].inherit_name != NULL ) &&
- (strcmp(interfaces[idx].inherit_name,
- interfaces[inf].name) == 0)) {
- interfaces[idx].inherit_idx = inf;
- interfaces[inf].refcount++;
- break;
- }
- }
- }
-}
-
-/** Topoligical sort based on the refcount
- *
- * do not need to consider loops as constructed graph is a acyclic
- *
- * alloc a second copy of the map
- * repeat until all entries copied:
- * walk source mapping until first entry with zero refcount
- * put the entry at the end of the output map
- * reduce refcount on inherit index if !=-1
- * remove entry from source map
- */
-static struct binding_interface *
-interface_topoligical_sort(struct binding_interface *srcinf, int infc)
-{
- struct binding_interface *dstinf;
- int idx;
- int inf;
-
- dstinf = calloc(infc, sizeof(struct binding_interface));
- if (dstinf == NULL) {
- return NULL;
- }
-
- for (idx = infc - 1; idx >= 0; idx--) {
- /* walk source map until first valid entry with zero refcount */
- inf = 0;
- while ((inf < infc) &&
- ((srcinf[inf].name == NULL) ||
- (srcinf[inf].refcount > 0))) {
- inf++;
- }
- if (inf == infc) {
- free(dstinf);
- return NULL;
- }
-
- /* copy entry to the end of the output map */
- dstinf[idx].name = srcinf[inf].name;
- dstinf[idx].node = srcinf[inf].node;
- dstinf[idx].widl_node = srcinf[inf].widl_node;
- dstinf[idx].inherit_name = srcinf[inf].inherit_name;
- dstinf[idx].own_properties = srcinf[inf].own_properties;
- dstinf[idx].own_functions = srcinf[inf].own_functions;
-
- /* reduce refcount on inherit index if !=-1 */
- if (srcinf[inf].inherit_idx != -1) {
- srcinf[srcinf[inf].inherit_idx].refcount--;
- }
-
- /* remove entry from source map */
- srcinf[inf].name = NULL;
- }
-
- return dstinf;
-}
-
-/* exported interface documented in jsapi-libdom.h */
-int build_interface_map(struct genbind_node *binding_node,
- struct webidl_node *webidl_ast,
- int *interfacec_out,
- struct binding_interface **interfaces_out)
-{
- int interfacec;
- int inf; /* interface loop counter */
- int idx; /* map index counter */
- struct binding_interface *interfaces;
- struct genbind_node *node = NULL;
- struct binding_interface *reinterfaces;
-
- /* count number of interfaces listed in binding */
- interfacec = genbind_node_enumerate_type(
- genbind_node_getnode(binding_node),
- GENBIND_NODE_TYPE_BINDING_INTERFACE);
-
- if (interfacec == 0) {
- return -1;
- }
- if (options->verbose) {
- printf("Binding has %d interfaces\n", interfacec);
- }
-
- interfaces = calloc(interfacec, sizeof(struct binding_interface));
- if (interfaces == NULL) {
- return -1;
- }
-
- /* fill in map with binding node data */
- idx = 0;
- node = genbind_node_find_type(genbind_node_getnode(binding_node),
- node,
- GENBIND_NODE_TYPE_BINDING_INTERFACE);
- while (node != NULL) {
-
- /* binding node */
- interfaces[idx].node = node;
-
- /* get interface name */
- interfaces[idx].name = genbind_node_gettext(
- genbind_node_find_type(genbind_node_getnode(node),
- NULL,
- GENBIND_NODE_TYPE_IDENT));
- if (interfaces[idx].name == NULL) {
- free(interfaces);
- return -1;
- }
-
- /* get interface info from webidl */
- if (fill_binding_interface(webidl_ast, interfaces + idx) == -1) {
- free(interfaces);
- return -1;
- }
-
- interfaces[idx].refcount = 0;
-
- /* ensure it is not a duplicate */
- for (inf = 0; inf < idx; inf++) {
- if (strcmp(interfaces[inf].name, interfaces[idx].name) == 0) {
- break;
- }
- }
- if (inf != idx) {
- WARN(WARNING_DUPLICATED,
- "interface %s duplicated in binding",
- interfaces[idx].name);
- } else {
- idx++;
- }
-
- /* next node */
- node = genbind_node_find_type(
- genbind_node_getnode(binding_node),
- node,
- GENBIND_NODE_TYPE_BINDING_INTERFACE);
- }
-
- /* update count which may have changed if there were duplicates */
- interfacec = idx;
-
- /* compute inheritance and refcounts on map */
- compute_inherit_refcount(interfaces, interfacec);
-
- /* the map must be augmented with all the interfaces not in
- * the binding but in the dependancy chain
- */
- for (idx = 0; idx < interfacec; idx++ ) {
- if ((interfaces[idx].inherit_idx == -1) &&
- (interfaces[idx].inherit_name != NULL)) {
- /* interface inherits but not currently in map */
-
- /* grow map */
- reinterfaces = realloc(interfaces,
- (interfacec + 1) * sizeof(struct binding_interface));
- if (reinterfaces == NULL) {
- fprintf(stderr,"Unable to grow interface map\n");
- free(interfaces);
- return -1;
- }
- interfaces = reinterfaces;
-
- /* setup all fields in new interface */
-
- /* this interface is not in the binding and
- * will not be exported
- */
- interfaces[interfacec].node = NULL;
-
- interfaces[interfacec].name = interfaces[idx].inherit_name;
-
- if (fill_binding_interface(webidl_ast,
- interfaces + interfacec) == -1) {
- fprintf(stderr,
- "Interface %s inherits from %s which is not in the WebIDL\n",
- interfaces[idx].name,
- interfaces[idx].inherit_name);
- free(interfaces);
- return -1;
- }
-
- interfaces[interfacec].inherit_idx = -1;
- interfaces[interfacec].refcount = 0;
-
- /* update dependancy info and refcount */
- for (inf = 0; inf < interfacec; inf++) {
- if (strcmp(interfaces[inf].inherit_name,
- interfaces[interfacec].name) == 0) {
- interfaces[inf].inherit_idx = interfacec;
- interfaces[interfacec].refcount++;
- }
- }
-
- /* update interface count in map */
- interfacec++;
-
- }
- }
-
- /* sort interfaces to ensure correct ordering */
- reinterfaces = interface_topoligical_sort(interfaces, interfacec);
- free(interfaces);
- if (reinterfaces == NULL) {
- return -1;
- }
- interfaces = reinterfaces;
-
- /* compute inheritance and refcounts on sorted map */
- compute_inherit_refcount(interfaces, interfacec);
-
- /* setup output index values */
- inf = 0;
- for (idx = 0; idx < interfacec; idx++ ) {
- if (interfaces[idx].node == NULL) {
- interfaces[idx].output_idx = -1;
- } else {
- interfaces[idx].output_idx = inf;
- inf++;
- }
- }
-
- /* show the interface map */
- if (options->verbose) {
- for (idx = 0; idx < interfacec; idx++ ) {
- printf("interface num:%d\n"
- " name:%s node:%p widl:%p\n"
- " inherit:%s inherit idx:%d refcount:%d\n"
- " own functions:%d own properties:%d output idx:%d\n",
- idx,
- interfaces[idx].name,
- interfaces[idx].node,
- interfaces[idx].widl_node,
- interfaces[idx].inherit_name,
- interfaces[idx].inherit_idx,
- interfaces[idx].refcount,
- interfaces[idx].own_functions,
- interfaces[idx].own_properties,
- interfaces[idx].output_idx);
- }
- }
-
- *interfacec_out = interfacec;
- *interfaces_out = interfaces;
-
- return 0;
-}
diff --git a/src/nsgenbind-ast.h b/src/nsgenbind-ast.h
index e7215b1..9c564b9 100644
--- a/src/nsgenbind-ast.h
+++ b/src/nsgenbind-ast.h
@@ -130,7 +130,7 @@ genbind_node_enumerate_type(struct genbind_node *node,
enum genbind_node_type type);
/** Depth first left hand search returning nodes of the specified type
- * and a ident child node with matching text
+ * with an ident child node with matching text
*
* @param node The node to start the search from
* @param prev The node at which to stop the search, either NULL to
diff --git a/src/nsgenbind.c b/src/nsgenbind.c
index 914f58e..18db196 100644
--- a/src/nsgenbind.c
+++ b/src/nsgenbind.c
@@ -14,10 +14,11 @@
#include <getopt.h>
#include <errno.h>
+#include "options.h"
#include "nsgenbind-ast.h"
#include "webidl-ast.h"
#include "jsapi-libdom.h"
-#include "options.h"
+#include "interface-map.h"
struct options *options;
@@ -194,6 +195,7 @@ int main(int argc, char **argv)
int res;
struct genbind_node *genbind_root = NULL;
struct webidl_node *webidl_root = NULL;
+ struct interface_map *interface_map = NULL;
enum bindingtype_e bindingtype;
options = process_cmdline(argc, argv);
@@ -226,6 +228,15 @@ int main(int argc, char **argv)
/* debug dump of web idl AST */
webidl_dump_ast(webidl_root);
+ /* generate index of interfaces in idl sorted by inheritance */
+ res = interface_map_new(genbind_root, webidl_root, &interface_map);
+ if (res != 0) {
+ return 5;
+ }
+
+ /* dump the interface mapping */
+ interface_map_dump(interface_map);
+ interface_map_dumpdot(interface_map);
#if 0
/* generate output for each binding */
diff --git a/test/data/bindings/browser-duk.bnd b/test/data/bindings/browser-duk.bnd
index c32f6a3..4e06d23 100644
--- a/test/data/bindings/browser-duk.bnd
+++ b/test/data/bindings/browser-duk.bnd
@@ -11,6 +11,7 @@
binding duk_libdom {
webidl "dom.idl";
webidl "html.idl";
+ webidl "uievents.idl";
webidl "console.idl";
preface %{
diff --git a/test/data/idl/uievents.idl b/test/data/idl/uievents.idl
new file mode 100644
index 0000000..3f339f3
--- /dev/null
+++ b/test/data/idl/uievents.idl
@@ -0,0 +1,185 @@
+// Retrived from
+// Thu Jul 23 21:40:07 BST 2015
+
+
+[Constructor(DOMString type, optional UIEventInit eventInitDict)]
+interface UIEvent : Event {
+ readonly attribute Window? view;
+ readonly attribute long detail;
+};
+
+dictionary UIEventInit : EventInit {
+ Window? view = null;
+ long detail = 0;
+};
+
+[Constructor(DOMString typeArg, optional FocusEventInit focusEventInitDict)]
+interface FocusEvent : UIEvent {
+ readonly attribute EventTarget? relatedTarget;
+};
+
+dictionary FocusEventInit : UIEventInit {
+ EventTarget? relatedTarget = null;
+};
+
+[Constructor(DOMString typeArg, optional MouseEventInit mouseEventInitDict)]
+interface MouseEvent : UIEvent {
+ readonly attribute long screenX;
+ readonly attribute long screenY;
+ readonly attribute long clientX;
+ readonly attribute long clientY;
+ readonly attribute boolean ctrlKey;
+ readonly attribute boolean shiftKey;
+ readonly attribute boolean altKey;
+ readonly attribute boolean metaKey;
+ readonly attribute short button;
+ readonly attribute EventTarget? relatedTarget;
+ // Introduced in this specification
+ readonly attribute unsigned short buttons;
+ boolean getModifierState (DOMString keyArg);
+};
+
+dictionary MouseEventInit : EventModifierInit {
+ long screenX = 0;
+ long screenY = 0;
+ long clientX = 0;
+ long clientY = 0;
+ short button = 0;
+ unsigned short buttons = 0;
+ EventTarget? relatedTarget = null;
+};
+
+dictionary EventModifierInit : UIEventInit {
+ boolean ctrlKey = false;
+ boolean shiftKey = false;
+ boolean altKey = false;
+ boolean metaKey = false;
+ boolean modifierAltGraph = false;
+ boolean modifierCapsLock = false;
+ boolean modifierFn = false;
+ boolean modifierFnLock = false;
+ boolean modifierHyper = false;
+ boolean modifierNumLock = false;
+ boolean modifierOS = false;
+ boolean modifierScrollLock = false;
+ boolean modifierSuper = false;
+ boolean modifierSymbol = false;
+ boolean modifierSymbolLock = false;
+};
+
+[Constructor(DOMString typeArg, optional WheelEventInit wheelEventInitDict)]
+interface WheelEvent : MouseEvent {
+ // DeltaModeCode
+ const unsigned long DOM_DELTA_PIXEL = 0x00;
+ const unsigned long DOM_DELTA_LINE = 0x01;
+ const unsigned long DOM_DELTA_PAGE = 0x02;
+ readonly attribute double deltaX;
+ readonly attribute double deltaY;
+ readonly attribute double deltaZ;
+ readonly attribute unsigned long deltaMode;
+};
+
+dictionary WheelEventInit : MouseEventInit {
+ double deltaX = 0.0;
+ double deltaY = 0.0;
+ double deltaZ = 0.0;
+ unsigned long deltaMode = 0;
+};
+
+[Constructor(DOMString typeArg, optional KeyboardEventInit keyboardEventInitDict)]
+interface KeyboardEvent : UIEvent {
+ // KeyLocationCode
+ const unsigned long DOM_KEY_LOCATION_STANDARD = 0x00;
+ const unsigned long DOM_KEY_LOCATION_LEFT = 0x01;
+ const unsigned long DOM_KEY_LOCATION_RIGHT = 0x02;
+ const unsigned long DOM_KEY_LOCATION_NUMPAD = 0x03;
+ readonly attribute DOMString key;
+ readonly attribute DOMString code;
+ readonly attribute unsigned long location;
+ readonly attribute boolean ctrlKey;
+ readonly attribute boolean shiftKey;
+ readonly attribute boolean altKey;
+ readonly attribute boolean metaKey;
+ readonly attribute boolean repeat;
+ readonly attribute boolean isComposing;
+ boolean getModifierState (DOMString keyArg);
+};
+
+dictionary KeyboardEventInit : EventModifierInit {
+ DOMString key = "";
+ DOMString code = "";
+ unsigned long location = 0;
+ boolean repeat = false;
+ boolean isComposing = false;
+};
+
+[Constructor(DOMString typeArg, optional CompositionEventInit compositionEventInitDict)]
+interface CompositionEvent : UIEvent {
+ readonly attribute DOMString data;
+};
+
+dictionary CompositionEventInit : UIEventInit {
+ DOMString data = "";
+};
+
+partial interface CustomEvent {
+ // Originally introduced (and deprecated) in this specification
+ void initCustomEvent (DOMString typeArg, boolean bubblesArg, boolean cancelableArg, any detailArg);
+};
+
+partial interface UIEvent {
+ // Deprecated in this specification
+ void initUIEvent (DOMString typeArg, boolean bubblesArg, boolean cancelableArg, Window? viewArg, long detailArg);
+};
+
+partial interface FocusEvent {
+ // Originally introduced (and deprecated) in this specification
+ void initFocusEvent (DOMString typeArg, boolean bubblesArg, boolean cancelableArg, Window? viewArg, long detailArg, EventTarget? relatedTargetArg);
+};
+
+partial interface MouseEvent {
+ // Deprecated in this specification
+ void initMouseEvent (DOMString typeArg, boolean bubblesArg, boolean cancelableArg, Window? viewArg, long detailArg, long screenXArg, long screenYArg, long clientXArg, long clientYArg, boolean ctrlKeyArg, boolean altKeyArg, boolean shiftKeyArg, boolean metaKeyArg, short buttonArg, EventTarget? relatedTargetArg);
+};
+
+partial interface WheelEvent {
+ // Originally introduced (and deprecated) in this specification
+ void initWheelEvent (DOMString typeArg, boolean bubblesArg, boolean cancelableArg, Window? viewArg, long detailArg, long screenXArg, long screenYArg, long clientXArg, long clientYArg, short buttonArg, EventTarget? relatedTargetArg, DOMString modifiersListArg, double deltaXArg, double deltaYArg, double deltaZArg, unsigned long deltaMode);
+};
+
+partial interface KeyboardEvent {
+ // Originally introduced (and deprecated) in this specification
+ void initKeyboardEvent (DOMString typeArg, boolean bubblesArg, boolean cancelableArg, Window? viewArg, DOMString keyArg, unsigned long locationArg, DOMString modifiersListArg, boolean repeat, DOMString locale);
+};
+
+partial interface CompositionEvent {
+ // Originally introduced (and deprecated) in this specification
+ void initCompositionEvent (DOMString typeArg, boolean bubblesArg, boolean cancelableArg, Window? viewArg, DOMString dataArg, DOMString locale);
+};
+
+partial interface KeyboardEvent {
+ // The following support legacy user agents
+ readonly attribute unsigned long charCode;
+ readonly attribute unsigned long keyCode;
+ readonly attribute unsigned long which;
+};
+
+partial dictionary KeyboardEventInit {
+ unsigned long charCode = 0;
+ unsigned long keyCode = 0;
+ unsigned long which = 0;
+};
+
+interface MutationEvent : Event {
+ // attrChangeType
+ const unsigned short MODIFICATION = 1;
+ const unsigned short ADDITION = 2;
+ const unsigned short REMOVAL = 3;
+ readonly attribute Node? relatedNode;
+ readonly attribute DOMString prevValue;
+ readonly attribute DOMString newValue;
+ readonly attribute DOMString attrName;
+ readonly attribute unsigned short attrChange;
+ void initMutationEvent (DOMString typeArg, boolean bubblesArg, boolean cancelableArg, Node? relatedNodeArg, DOMString prevValueArg, DOMString newValueArg, DOMString attrNameArg, unsigned short attrChangeArg);
+};
+