summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorVincent Sanders <vince@kyllikki.org>2015-07-21 23:48:45 +0100
committerVincent Sanders <vince@kyllikki.org>2015-07-21 23:48:45 +0100
commit1288d8c535edd2ce29eebdc4acca6b2beab89841 (patch)
tree162bd2d090e03a7ffb9523797c1dd2aebbce236f /src
parent94137186a3e2270e9b96f243a82a77a590c17f01 (diff)
downloadnsgenbind-1288d8c535edd2ce29eebdc4acca6b2beab89841.tar.gz
nsgenbind-1288d8c535edd2ce29eebdc4acca6b2beab89841.tar.bz2
Change binding grammar to new approach.
Diffstat (limited to 'src')
-rw-r--r--src/Makefile3
-rw-r--r--src/nsgenbind-ast.c759
-rw-r--r--src/nsgenbind-ast.h113
-rw-r--r--src/nsgenbind-lexer.l39
-rw-r--r--src/nsgenbind-parser.y386
-rw-r--r--src/nsgenbind.c324
-rw-r--r--src/options.h15
-rw-r--r--src/utils.c52
-rw-r--r--src/utils.h21
9 files changed, 937 insertions, 775 deletions
diff --git a/src/Makefile b/src/Makefile
index e93cb99..3e5b8af 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -1,7 +1,8 @@
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-function.c jsapi-libdom-property.c jsapi-libdom-init.c jsapi-libdom-new.c jsapi-libdom-infmap.c jsapi-libdom-jsclass.c
+DIR_SOURCES := nsgenbind.c utils.c webidl-ast.c nsgenbind-ast.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/nsgenbind-ast.c b/src/nsgenbind-ast.c
index 2f630b7..49477cf 100644
--- a/src/nsgenbind-ast.c
+++ b/src/nsgenbind-ast.c
@@ -14,7 +14,9 @@
#include <stdlib.h>
#include <errno.h>
#include <string.h>
+#include <stdarg.h>
+#include "utils.h"
#include "nsgenbind-ast.h"
#include "options.h"
@@ -26,478 +28,521 @@ extern int nsgenbind_parse(struct genbind_node **genbind_ast);
/* terminal nodes have a value only */
struct genbind_node {
- enum genbind_node_type type;
- struct genbind_node *l;
- union {
- void *value;
- struct genbind_node *node;
- char *text;
- int number; /* node data is an integer */
- } r;
+ enum genbind_node_type type;
+ struct genbind_node *l;
+ union {
+ void *value;
+ struct genbind_node *node;
+ char *text;
+ int number; /* node data is an integer */
+ } r;
};
char *genbind_strapp(char *a, char *b)
{
- char *fullstr;
- int fulllen;
- fulllen = strlen(a) + strlen(b) + 1;
- fullstr = malloc(fulllen);
- snprintf(fullstr, fulllen, "%s%s", a, b);
- free(a);
- free(b);
- return fullstr;
+ char *fullstr;
+ int fulllen;
+ fulllen = strlen(a) + strlen(b) + 1;
+ fullstr = malloc(fulllen);
+ snprintf(fullstr, fulllen, "%s%s", a, b);
+ free(a);
+ free(b);
+ return fullstr;
}
struct genbind_node *
genbind_node_link(struct genbind_node *tgt, struct genbind_node *src)
{
- tgt->l = src;
- return tgt;
+ tgt->l = src;
+ return tgt;
}
struct genbind_node *
genbind_new_node(enum genbind_node_type type, struct genbind_node *l, void *r)
{
- struct genbind_node *nn;
- nn = calloc(1, sizeof(struct genbind_node));
- nn->type = type;
- nn->l = l;
- nn->r.value = r;
- return nn;
+ struct genbind_node *nn;
+ nn = calloc(1, sizeof(struct genbind_node));
+ nn->type = type;
+ nn->l = l;
+ nn->r.value = r;
+ return nn;
}
/* exported interface defined in nsgenbind-ast.h */
int
genbind_node_foreach_type(struct genbind_node *node,
- enum genbind_node_type type,
- genbind_callback_t *cb,
- void *ctx)
+ enum genbind_node_type type,
+ genbind_callback_t *cb,
+ void *ctx)
{
- int ret;
-
- if (node == NULL) {
- return -1;
- }
- if (node->l != NULL) {
- ret = genbind_node_foreach_type(node->l, type, cb, ctx);
- if (ret != 0) {
- return ret;
- }
- }
- if (node->type == type) {
- return cb(node, ctx);
- }
-
- return 0;
+ int ret;
+
+ if (node == NULL) {
+ return -1;
+ }
+ if (node->l != NULL) {
+ ret = genbind_node_foreach_type(node->l, type, cb, ctx);
+ if (ret != 0) {
+ return ret;
+ }
+ }
+ if (node->type == type) {
+ return cb(node, ctx);
+ }
+
+ return 0;
}
static int genbind_enumerate_node(struct genbind_node *node, void *ctx)
{
- node = node;
- (*((int *)ctx))++;
- return 0;
+ node = node;
+ (*((int *)ctx))++;
+ return 0;
}
/* exported interface defined in nsgenbind-ast.h */
int
genbind_node_enumerate_type(struct genbind_node *node,
- enum genbind_node_type type)
+ enum genbind_node_type type)
{
- int count = 0;
- genbind_node_foreach_type(node,
- type,
- genbind_enumerate_node,
- &count);
- return count;
+ int count = 0;
+ genbind_node_foreach_type(node,
+ type,
+ genbind_enumerate_node,
+ &count);
+ return count;
}
/* exported interface defined in nsgenbind-ast.h */
struct genbind_node *
genbind_node_find(struct genbind_node *node,
- struct genbind_node *prev,
- genbind_callback_t *cb,
- void *ctx)
+ struct genbind_node *prev,
+ genbind_callback_t *cb,
+ void *ctx)
{
- struct genbind_node *ret;
+ struct genbind_node *ret;
- if ((node == NULL) || (node == prev)) {
- return NULL;
- }
+ if ((node == NULL) || (node == prev)) {
+ return NULL;
+ }
- if (node->l != prev) {
- ret = genbind_node_find(node->l, prev, cb, ctx);
- if (ret != NULL) {
- return ret;
- }
- }
+ if (node->l != prev) {
+ ret = genbind_node_find(node->l, prev, cb, ctx);
+ if (ret != NULL) {
+ return ret;
+ }
+ }
- if (cb(node, ctx) != 0) {
- return node;
- }
+ if (cb(node, ctx) != 0) {
+ return node;
+ }
- return NULL;
+ return NULL;
}
/* exported interface documented in nsgenbind-ast.h */
struct genbind_node *
genbind_node_find_type(struct genbind_node *node,
- struct genbind_node *prev,
- enum genbind_node_type type)
+ struct genbind_node *prev,
+ enum genbind_node_type type)
{
- return genbind_node_find(node,
- prev,
- genbind_cmp_node_type,
- (void *)type);
+ return genbind_node_find(node,
+ prev,
+ genbind_cmp_node_type,
+ (void *)type);
}
/* exported interface documented in nsgenbind-ast.h */
struct genbind_node *
genbind_node_find_type_ident(struct genbind_node *node,
- struct genbind_node *prev,
- enum genbind_node_type type,
- const char *ident)
+ struct genbind_node *prev,
+ enum genbind_node_type type,
+ const char *ident)
{
- struct genbind_node *found_node;
- struct genbind_node *ident_node;
-
- if (ident == NULL) {
- return NULL;
- }
-
- found_node = genbind_node_find_type(node, prev, type);
-
- while (found_node != NULL) {
- /* look for an ident node */
- ident_node = genbind_node_find_type(
- genbind_node_getnode(found_node),
- NULL,
- GENBIND_NODE_TYPE_IDENT);
-
- while (ident_node != NULL) {
- /* check for matching text */
- if (strcmp(ident_node->r.text, ident) == 0) {
- return found_node;
- }
-
- ident_node = genbind_node_find_type(
- genbind_node_getnode(found_node),
- ident_node,
- GENBIND_NODE_TYPE_IDENT);
- }
-
-
- /* look for next matching node */
- found_node = genbind_node_find_type(node, found_node, type);
- }
- return found_node;
+ struct genbind_node *found_node;
+ struct genbind_node *ident_node;
+
+ if (ident == NULL) {
+ return NULL;
+ }
+
+ found_node = genbind_node_find_type(node, prev, type);
+
+ while (found_node != NULL) {
+ /* look for an ident node */
+ ident_node = genbind_node_find_type(
+ genbind_node_getnode(found_node),
+ NULL,
+ GENBIND_NODE_TYPE_IDENT);
+
+ while (ident_node != NULL) {
+ /* check for matching text */
+ if (strcmp(ident_node->r.text, ident) == 0) {
+ return found_node;
+ }
+
+ ident_node = genbind_node_find_type(
+ genbind_node_getnode(found_node),
+ ident_node,
+ GENBIND_NODE_TYPE_IDENT);
+ }
+
+
+ /* look for next matching node */
+ found_node = genbind_node_find_type(node, found_node, type);
+ }
+ return found_node;
}
/* exported interface documented in nsgenbind-ast.h */
struct genbind_node *
genbind_node_find_type_type(struct genbind_node *node,
- struct genbind_node *prev,
- enum genbind_node_type type,
- const char *ident)
+ struct genbind_node *prev,
+ enum genbind_node_type type,
+ const char *ident)
{
- struct genbind_node *found_node;
- struct genbind_node *ident_node;
-
- found_node = genbind_node_find_type(node, prev, type);
-
-
- while (found_node != NULL) {
- /* look for a type node */
- ident_node = genbind_node_find_type(genbind_node_getnode(found_node),
- NULL,
- GENBIND_NODE_TYPE_TYPE);
- if (ident_node != NULL) {
- if (strcmp(ident_node->r.text, ident) == 0)
- break;
- }
-
- /* look for next matching node */
- found_node = genbind_node_find_type(node, found_node, type);
- }
- return found_node;
+ struct genbind_node *found_node;
+ struct genbind_node *ident_node;
+
+ found_node = genbind_node_find_type(node, prev, type);
+
+
+ while (found_node != NULL) {
+ /* look for a type node */
+ ident_node = genbind_node_find_type(genbind_node_getnode(found_node),
+ NULL,
+ GENBIND_NODE_TYPE_TYPE);
+ if (ident_node != NULL) {
+ if (strcmp(ident_node->r.text, ident) == 0)
+ break;
+ }
+
+ /* look for next matching node */
+ found_node = genbind_node_find_type(node, found_node, type);
+ }
+ return found_node;
}
int genbind_cmp_node_type(struct genbind_node *node, void *ctx)
{
- if (node->type == (enum genbind_node_type)ctx)
- return 1;
- return 0;
+ if (node->type == (enum genbind_node_type)ctx)
+ return 1;
+ return 0;
}
char *genbind_node_gettext(struct genbind_node *node)
{
- if (node != NULL) {
- switch(node->type) {
- case GENBIND_NODE_TYPE_WEBIDLFILE:
- case GENBIND_NODE_TYPE_STRING:
- case GENBIND_NODE_TYPE_PREAMBLE:
- case GENBIND_NODE_TYPE_PROLOGUE:
- case GENBIND_NODE_TYPE_EPILOGUE:
- case GENBIND_NODE_TYPE_IDENT:
- case GENBIND_NODE_TYPE_TYPE:
- case GENBIND_NODE_TYPE_CBLOCK:
- return node->r.text;
-
- default:
- break;
- }
- }
- return NULL;
+ if (node != NULL) {
+ switch(node->type) {
+ case GENBIND_NODE_TYPE_WEBIDL:
+ case GENBIND_NODE_TYPE_STRING:
+ case GENBIND_NODE_TYPE_PREFACE:
+ case GENBIND_NODE_TYPE_PROLOGUE:
+ case GENBIND_NODE_TYPE_EPILOGUE:
+ case GENBIND_NODE_TYPE_POSTFACE:
+ case GENBIND_NODE_TYPE_IDENT:
+ case GENBIND_NODE_TYPE_TYPE:
+ case GENBIND_NODE_TYPE_CDATA:
+ return node->r.text;
+
+ default:
+ break;
+ }
+ }
+ return NULL;
}
struct genbind_node *genbind_node_getnode(struct genbind_node *node)
{
- if (node != NULL) {
- switch(node->type) {
- case GENBIND_NODE_TYPE_HDRCOMMENT:
- case GENBIND_NODE_TYPE_BINDING:
- case GENBIND_NODE_TYPE_BINDING_PRIVATE:
- case GENBIND_NODE_TYPE_BINDING_INTERNAL:
- case GENBIND_NODE_TYPE_BINDING_PROPERTY:
- case GENBIND_NODE_TYPE_BINDING_INTERFACE:
- case GENBIND_NODE_TYPE_BINDING_INTERFACE_FLAGS:
- case GENBIND_NODE_TYPE_OPERATION:
- case GENBIND_NODE_TYPE_API:
- case GENBIND_NODE_TYPE_GETTER:
- case GENBIND_NODE_TYPE_SETTER:
- return node->r.node;
-
- default:
- break;
- }
- }
- return NULL;
+ if (node != NULL) {
+ switch(node->type) {
+ case GENBIND_NODE_TYPE_BINDING:
+ case GENBIND_NODE_TYPE_CLASS:
+ case GENBIND_NODE_TYPE_PRIVATE:
+ case GENBIND_NODE_TYPE_INTERNAL:
+ case GENBIND_NODE_TYPE_PROPERTY:
+ case GENBIND_NODE_TYPE_FLAGS:
+ case GENBIND_NODE_TYPE_METHOD:
+ case GENBIND_NODE_TYPE_PARAMETER:
+ return node->r.node;
+
+ default:
+ break;
+ }
+ }
+ return NULL;
}
int *genbind_node_getint(struct genbind_node *node)
{
- if (node != NULL) {
- switch(node->type) {
- case GENBIND_NODE_TYPE_MODIFIER:
- return &node->r.number;
-
- default:
- break;
- }
- }
- return NULL;
+ if (node != NULL) {
+ switch(node->type) {
+ case GENBIND_NODE_TYPE_METHOD_TYPE:
+ case GENBIND_NODE_TYPE_MODIFIER:
+ return &node->r.number;
+
+ default:
+ break;
+ }
+ }
+ return NULL;
}
static const char *genbind_node_type_to_str(enum genbind_node_type type)
{
- switch(type) {
- case GENBIND_NODE_TYPE_IDENT:
- return "Ident";
+ switch(type) {
+ case GENBIND_NODE_TYPE_IDENT:
+ return "Ident";
- case GENBIND_NODE_TYPE_ROOT:
- return "Root";
+ case GENBIND_NODE_TYPE_ROOT:
+ return "Root";
- case GENBIND_NODE_TYPE_WEBIDLFILE:
- return "webidlfile";
+ case GENBIND_NODE_TYPE_WEBIDL:
+ return "webidl";
- case GENBIND_NODE_TYPE_HDRCOMMENT:
- return "HdrComment";
+ case GENBIND_NODE_TYPE_STRING:
+ return "String";
- case GENBIND_NODE_TYPE_STRING:
- return "String";
+ case GENBIND_NODE_TYPE_PREFACE:
+ return "Preface";
- case GENBIND_NODE_TYPE_PREAMBLE:
- return "Preamble";
+ case GENBIND_NODE_TYPE_POSTFACE:
+ return "Postface";
- case GENBIND_NODE_TYPE_BINDING:
- return "Binding";
+ case GENBIND_NODE_TYPE_PROLOGUE:
+ return "Prologue";
- case GENBIND_NODE_TYPE_TYPE:
- return "Type";
+ case GENBIND_NODE_TYPE_EPILOGUE:
+ return "Epilogue";
- case GENBIND_NODE_TYPE_BINDING_PRIVATE:
- return "Private";
+ case GENBIND_NODE_TYPE_BINDING:
+ return "Binding";
- case GENBIND_NODE_TYPE_BINDING_INTERNAL:
- return "Internal";
+ case GENBIND_NODE_TYPE_TYPE:
+ return "Type";
- case GENBIND_NODE_TYPE_BINDING_INTERFACE:
- return "Interface";
+ case GENBIND_NODE_TYPE_PRIVATE:
+ return "Private";
- case GENBIND_NODE_TYPE_BINDING_INTERFACE_FLAGS:
- return "Flags";
+ case GENBIND_NODE_TYPE_INTERNAL:
+ return "Internal";
- case GENBIND_NODE_TYPE_BINDING_PROPERTY:
- return "Property";
+ case GENBIND_NODE_TYPE_CLASS:
+ return "Class";
- case GENBIND_NODE_TYPE_OPERATION:
- return "Operation";
+ case GENBIND_NODE_TYPE_FLAGS:
+ return "Flags";
- case GENBIND_NODE_TYPE_API:
- return "API";
+ case GENBIND_NODE_TYPE_PROPERTY:
+ return "Property";
- case GENBIND_NODE_TYPE_GETTER:
- return "Getter";
+ case GENBIND_NODE_TYPE_METHOD:
+ return "Method";
- case GENBIND_NODE_TYPE_SETTER:
- return "Setter";
+ case GENBIND_NODE_TYPE_METHOD_TYPE:
+ return "Type";
- case GENBIND_NODE_TYPE_CBLOCK:
- return "CBlock";
+ case GENBIND_NODE_TYPE_PARAMETER:
+ return "Parameter";
- default:
- return "Unknown";
- }
+ case GENBIND_NODE_TYPE_CDATA:
+ return "CBlock";
+
+ default:
+ return "Unknown";
+ }
}
-int genbind_ast_dump(struct genbind_node *node, int indent)
+/** dump ast node to file at indent level */
+static int genbind_ast_dump(FILE *dfile, struct genbind_node *node, int indent)
{
- const char *SPACES=" ";
- char *txt;
-
- while (node != NULL) {
- printf("%.*s%s", indent, SPACES, genbind_node_type_to_str(node->type));
-
- txt = genbind_node_gettext(node);
- if (txt == NULL) {
- printf("\n");
- genbind_ast_dump(genbind_node_getnode(node), indent + 2);
- } else {
- printf(": \"%.*s\"\n", 75 - indent, txt);
- }
- node = node->l;
- }
- return 0;
+ const char *SPACES=" ";
+ char *txt;
+ int *val;
+
+ while (node != NULL) {
+ fprintf(dfile, "%.*s%s", indent, SPACES,
+ genbind_node_type_to_str(node->type));
+
+ txt = genbind_node_gettext(node);
+ if (txt == NULL) {
+ val = genbind_node_getint(node);
+ if (val == NULL) {
+ fprintf(dfile, "\n");
+ genbind_ast_dump(dfile,
+ genbind_node_getnode(node),
+ indent + 2);
+ } else {
+ fprintf(dfile, ": %d\n", *val);
+ }
+ } else {
+ fprintf(dfile, ": \"%.*s\"\n", 75 - indent, txt);
+ }
+ node = node->l;
+ }
+ return 0;
}
-FILE *genbindopen(const char *filename)
+
+/* exported interface documented in nsgenbind-ast.h */
+int genbind_dump_ast(struct genbind_node *node)
{
- FILE *genfile;
- char *fullname;
- int fulllen;
- static char *prevfilepath = NULL;
-
- /* try filename raw */
- genfile = fopen(filename, "r");
- if (genfile != NULL) {
- if (options->verbose) {
- printf("Opened Genbind file %s\n", filename);
- }
- if (prevfilepath == NULL) {
- fullname = strrchr(filename, '/');
- if (fullname == NULL) {
- fulllen = strlen(filename);
- } else {
- fulllen = fullname - filename;
- }
- prevfilepath = strndup(filename,fulllen);
- }
- if (options->depfilehandle != NULL) {
- fprintf(options->depfilehandle, " \\\n\t%s",
- filename);
- }
- return genfile;
- }
-
- /* try based on previous filename */
- if (prevfilepath != NULL) {
- fulllen = strlen(prevfilepath) + strlen(filename) + 2;
- fullname = malloc(fulllen);
- snprintf(fullname, fulllen, "%s/%s", prevfilepath, filename);
- if (options->debug) {
- printf("Attempting to open Genbind file %s\n", fullname);
- }
- genfile = fopen(fullname, "r");
- if (genfile != NULL) {
- if (options->verbose) {
- printf("Opened Genbind file %s\n", fullname);
- }
- if (options->depfilehandle != NULL) {
- fprintf(options->depfilehandle, " \\\n\t%s",
- fullname);
- }
- free(fullname);
- return genfile;
- }
- free(fullname);
- }
-
- /* try on idl path */
- if (options->idlpath != NULL) {
- fulllen = strlen(options->idlpath) + strlen(filename) + 2;
- fullname = malloc(fulllen);
- snprintf(fullname, fulllen, "%s/%s", options->idlpath, filename);
- genfile = fopen(fullname, "r");
- if ((genfile != NULL) && options->verbose) {
- printf("Opend Genbind file %s\n", fullname);
- if (options->depfilehandle != NULL) {
- fprintf(options->depfilehandle, " \\\n\t%s",
- fullname);
- }
- }
-
- free(fullname);
- }
-
- return genfile;
+ FILE *dumpf;
+
+ /* only dump AST to file if required */
+ if (!options->debug) {
+ return 0;
+ }
+
+ dumpf = genb_fopen("binding-ast", "w");
+ if (dumpf == NULL) {
+ return 2;
+ }
+
+ genbind_ast_dump(dumpf, node, 0);
+
+ fclose(dumpf);
+
+ return 0;
}
-int genbind_parsefile(char *infilename, struct genbind_node **ast)
+FILE *genbindopen(const char *filename)
{
- FILE *infile;
-
- /* open input file */
- if ((infilename[0] == '-') &&
- (infilename[1] == 0)) {
- if (options->verbose) {
- printf("Using stdin for input\n");
- }
- infile = stdin;
- } else {
- infile = genbindopen(infilename);
- }
-
- if (!infile) {
- fprintf(stderr, "Error opening %s: %s\n",
- infilename,
- strerror(errno));
- return 3;
- }
-
- if (options->debug) {
- nsgenbind_debug = 1;
- nsgenbind__flex_debug = 1;
- }
-
- /* set flex to read from file */
- nsgenbind_restart(infile);
-
- /* process binding */
- return nsgenbind_parse(ast);
+ FILE *genfile;
+ char *fullname;
+ int fulllen;
+ static char *prevfilepath = NULL;
+
+ /* try filename raw */
+ genfile = fopen(filename, "r");
+ if (genfile != NULL) {
+ if (options->verbose) {
+ printf("Opened Genbind file %s\n", filename);
+ }
+ if (prevfilepath == NULL) {
+ fullname = strrchr(filename, '/');
+ if (fullname == NULL) {
+ fulllen = strlen(filename);
+ } else {
+ fulllen = fullname - filename;
+ }
+ prevfilepath = strndup(filename,fulllen);
+ }
+#if 0
+ if (options->depfilehandle != NULL) {
+ fprintf(options->depfilehandle, " \\\n\t%s",
+ filename);
+ }
+#endif
+ return genfile;
+ }
+
+ /* try based on previous filename */
+ if (prevfilepath != NULL) {
+ fulllen = strlen(prevfilepath) + strlen(filename) + 2;
+ fullname = malloc(fulllen);
+ snprintf(fullname, fulllen, "%s/%s", prevfilepath, filename);
+ if (options->debug) {
+ printf("Attempting to open Genbind file %s\n", fullname);
+ }
+ genfile = fopen(fullname, "r");
+ if (genfile != NULL) {
+ if (options->verbose) {
+ printf("Opened Genbind file %s\n", fullname);
+ }
+#if 0
+ if (options->depfilehandle != NULL) {
+ fprintf(options->depfilehandle, " \\\n\t%s",
+ fullname);
+ }
+#endif
+ free(fullname);
+ return genfile;
+ }
+ free(fullname);
+ }
+
+ /* try on idl path */
+ if (options->idlpath != NULL) {
+ fulllen = strlen(options->idlpath) + strlen(filename) + 2;
+ fullname = malloc(fulllen);
+ snprintf(fullname, fulllen, "%s/%s", options->idlpath, filename);
+ genfile = fopen(fullname, "r");
+ if ((genfile != NULL) && options->verbose) {
+ printf("Opend Genbind file %s\n", fullname);
+#if 0
+ if (options->depfilehandle != NULL) {
+ fprintf(options->depfilehandle, " \\\n\t%s",
+ fullname);
+ }
+#endif
+ }
+
+ free(fullname);
+ }
+ return genfile;
}
-#ifdef NEED_STRNDUP
+/**
+ * standard IO handle for parse trace logging.
+ */
+static FILE *genbind_parsetracef;
-char *strndup(const char *s, size_t n)
+int genbind_parsefile(char *infilename, struct genbind_node **ast)
{
- size_t len;
- char *s2;
-
- for (len = 0; len != n && s[len]; len++)
- continue;
+ FILE *infile;
+ int ret;
+
+ /* open input file */
+ infile = genbindopen(infilename);
+ if (!infile) {
+ fprintf(stderr, "Error opening %s: %s\n",
+ infilename,
+ strerror(errno));
+ return 3;
+ }
+
+ /* if debugging enabled enable parser tracing and send to file */
+ if (options->debug) {
+ nsgenbind_debug = 1;
+ nsgenbind__flex_debug = 1;
+ genbind_parsetracef = genb_fopen("binding-trace", "w");
+ } else {
+ genbind_parsetracef = NULL;
+ }
+
+ /* set flex to read from file */
+ nsgenbind_restart(infile);
+
+ /* process binding */
+ ret = nsgenbind_parse(ast);
+
+ /* close tracefile if open */
+ if (genbind_parsetracef != NULL) {
+ fclose(genbind_parsetracef);
+ }
+
+ return ret;
+}
- s2 = malloc(len + 1);
- if (!s2)
- return 0;
+int genbind_fprintf(FILE *stream, const char *format, ...)
+{
+ va_list ap;
+ int ret;
- memcpy(s2, s, len);
- s2[len] = 0;
- return s2;
-}
+ va_start(ap, format);
-#endif
+ if (genbind_parsetracef == NULL) {
+ ret = vfprintf(stream, format, ap);
+ } else {
+ ret = vfprintf(genbind_parsetracef, format, ap);
+ }
+ va_end(ap);
+ return ret;
+}
diff --git a/src/nsgenbind-ast.h b/src/nsgenbind-ast.h
index 4911f5a..f6800fb 100644
--- a/src/nsgenbind-ast.h
+++ b/src/nsgenbind-ast.h
@@ -10,36 +10,46 @@
#define nsgenbind_nsgenbind_ast_h
enum genbind_node_type {
- GENBIND_NODE_TYPE_ROOT = 0,
- GENBIND_NODE_TYPE_IDENT, /**< generic identifier string */
- GENBIND_NODE_TYPE_TYPE, /**< generic type string */
- GENBIND_NODE_TYPE_MODIFIER, /**< node modifier */
-
- GENBIND_NODE_TYPE_CBLOCK,
- GENBIND_NODE_TYPE_WEBIDLFILE,
- GENBIND_NODE_TYPE_HDRCOMMENT,
- GENBIND_NODE_TYPE_STRING,
- GENBIND_NODE_TYPE_PREAMBLE,
- GENBIND_NODE_TYPE_PROLOGUE,
- GENBIND_NODE_TYPE_EPILOGUE,
- GENBIND_NODE_TYPE_BINDING,
- GENBIND_NODE_TYPE_BINDING_PRIVATE,
- GENBIND_NODE_TYPE_BINDING_INTERNAL,
- GENBIND_NODE_TYPE_BINDING_INTERFACE,
- GENBIND_NODE_TYPE_BINDING_INTERFACE_FLAGS,
- GENBIND_NODE_TYPE_BINDING_PROPERTY,
- GENBIND_NODE_TYPE_API,
- GENBIND_NODE_TYPE_OPERATION,
- GENBIND_NODE_TYPE_GETTER,
- GENBIND_NODE_TYPE_SETTER,
+ GENBIND_NODE_TYPE_ROOT = 0,
+ GENBIND_NODE_TYPE_IDENT, /**< generic identifier string */
+ GENBIND_NODE_TYPE_TYPE, /**< generic type string */
+ GENBIND_NODE_TYPE_MODIFIER, /**< node modifier */
+ GENBIND_NODE_TYPE_CDATA, /**< verbatim block of character data */
+ GENBIND_NODE_TYPE_STRING, /**< text string */
+
+ GENBIND_NODE_TYPE_BINDING,
+ GENBIND_NODE_TYPE_WEBIDL,
+ GENBIND_NODE_TYPE_PREFACE,
+ GENBIND_NODE_TYPE_PROLOGUE,
+ GENBIND_NODE_TYPE_EPILOGUE,
+ GENBIND_NODE_TYPE_POSTFACE,
+
+ GENBIND_NODE_TYPE_CLASS, /**< class definition */
+ GENBIND_NODE_TYPE_PRIVATE,
+ GENBIND_NODE_TYPE_INTERNAL,
+ GENBIND_NODE_TYPE_PROPERTY,
+ GENBIND_NODE_TYPE_FLAGS,
+
+ GENBIND_NODE_TYPE_METHOD, /**< binding method */
+ GENBIND_NODE_TYPE_METHOD_TYPE, /**< binding method type */
+ GENBIND_NODE_TYPE_PARAMETER, /**< method parameter */
};
/* modifier flags */
enum genbind_type_modifier {
- GENBIND_TYPE_NONE = 0,
- GENBIND_TYPE_TYPE = 1, /**< identifies a type handler */
- GENBIND_TYPE_UNSHARED = 2, /**< unshared item */
- GENBIND_TYPE_TYPE_UNSHARED = 3, /**< identifies a unshared type handler */
+ GENBIND_TYPE_NONE = 0,
+ GENBIND_TYPE_TYPE = 1, /**< identifies a type handler */
+ GENBIND_TYPE_UNSHARED = 2, /**< unshared item */
+ GENBIND_TYPE_TYPE_UNSHARED = 3, /**< identifies a unshared type handler */
+};
+
+/* binding method types */
+enum genbind_method_type {
+ GENBIND_METHOD_TYPE_INIT = 0,
+ GENBIND_METHOD_TYPE_FINI = 1, /**< */
+ GENBIND_METHOD_TYPE_METHOD = 2, /**< */
+ GENBIND_METHOD_TYPE_GETTER = 3, /**< */
+ GENBIND_METHOD_TYPE_SETTER = 4, /**< */
};
struct genbind_node;
@@ -47,6 +57,8 @@ struct genbind_node;
/** callback for search and iteration routines */
typedef int (genbind_callback_t)(struct genbind_node *node, void *ctx);
+int genbind_fprintf(FILE *stream, const char *format, ...);
+
int genbind_cmp_node_type(struct genbind_node *node, void *ctx);
FILE *genbindopen(const char *filename);
@@ -58,9 +70,19 @@ char *genbind_strapp(char *a, char *b);
struct genbind_node *genbind_new_node(enum genbind_node_type type, struct genbind_node *l, void *r);
struct genbind_node *genbind_node_link(struct genbind_node *tgt, struct genbind_node *src);
-int genbind_ast_dump(struct genbind_node *ast, int indent);
+/**
+ * Dump the binding AST to file
+ *
+ * If the debug flag has been set this causes the binding AST to be written to
+ * a binding-ast output file
+ *
+ * \param node Node of the tree to start dumping from (usually tree root)
+ * \return 0 on sucess or non zero on faliure and error message printed.
+ */
+int genbind_dump_ast(struct genbind_node *node);
-/** Depth first left hand search using user provided comparison
+/**
+ *Depth first left hand search using user provided comparison
*
* @param node The node to start the search from
* @param prev The node at which to stop the search, either NULL to
@@ -71,9 +93,9 @@ int genbind_ast_dump(struct genbind_node *ast, int indent);
*/
struct genbind_node *
genbind_node_find(struct genbind_node *node,
- struct genbind_node *prev,
- genbind_callback_t *cb,
- void *ctx);
+ struct genbind_node *prev,
+ genbind_callback_t *cb,
+ void *ctx);
/** Depth first left hand search returning nodes of the specified type
*
@@ -86,8 +108,8 @@ genbind_node_find(struct genbind_node *node,
*/
struct genbind_node *
genbind_node_find_type(struct genbind_node *node,
- struct genbind_node *prev,
- enum genbind_node_type nodetype);
+ struct genbind_node *prev,
+ enum genbind_node_type nodetype);
/** count how many nodes of a specified type.
*
@@ -101,7 +123,7 @@ genbind_node_find_type(struct genbind_node *node,
*/
int
genbind_node_enumerate_type(struct genbind_node *node,
- enum genbind_node_type type);
+ enum genbind_node_type type);
/** Depth first left hand search returning nodes of the specified type
* and a ident child node with matching text
@@ -115,9 +137,9 @@ genbind_node_enumerate_type(struct genbind_node *node,
*/
struct genbind_node *
genbind_node_find_type_ident(struct genbind_node *node,
- struct genbind_node *prev,
- enum genbind_node_type nodetype,
- const char *ident);
+ struct genbind_node *prev,
+ enum genbind_node_type nodetype,
+ const char *ident);
/** Returning node of the specified type with a GENBIND_NODE_TYPE_TYPE
* subnode with matching text.
@@ -137,9 +159,9 @@ genbind_node_find_type_ident(struct genbind_node *node,
*/
struct genbind_node *
genbind_node_find_type_type(struct genbind_node *node,
- struct genbind_node *prev,
- enum genbind_node_type nodetype,
- const char *type_text);
+ struct genbind_node *prev,
+ enum genbind_node_type nodetype,
+ const char *type_text);
/** Iterate all nodes of a certian type from a node with a callback.
*
@@ -149,9 +171,9 @@ genbind_node_find_type_type(struct genbind_node *node,
* @param node The node to start the search from.
*/
int genbind_node_foreach_type(struct genbind_node *node,
- enum genbind_node_type type,
- genbind_callback_t *cb,
- void *ctx);
+ enum genbind_node_type type,
+ genbind_callback_t *cb,
+ void *ctx);
/** get a nodes node list content
*
@@ -176,9 +198,4 @@ char *genbind_node_gettext(struct genbind_node *node);
*/
int *genbind_node_getint(struct genbind_node *node);
-#ifdef _WIN32
-#define NEED_STRNDUP 1
-char *strndup(const char *s, size_t n);
-#endif
-
#endif
diff --git a/src/nsgenbind-lexer.l b/src/nsgenbind-lexer.l
index 4b5e225..f7b6528 100644
--- a/src/nsgenbind-lexer.l
+++ b/src/nsgenbind-lexer.l
@@ -72,7 +72,9 @@ cblockopen \%\{
cblockclose \%\}
/* used for #include directive */
-poundsign ^{whitespace}*#
+poundsign ^{whitespace}*#
+
+dblcolon \:\:
%x cblock
@@ -88,44 +90,55 @@ poundsign ^{whitespace}*#
yylloc->last_column = 0;
}
- /* terminals */
+ /* binding terminals */
-webidlfile return TOK_IDLFILE;
+binding return TOK_BINDING;
-hdrcomment return TOK_HDR_COMMENT;
+webidl return TOK_WEBIDL;
-preamble return TOK_PREAMBLE;
+preface return TOK_PREFACE;
prologue return TOK_PROLOGUE;
epilogue return TOK_EPILOGUE;
-binding return TOK_BINDING;
+postface return TOK_POSTFACE;
-interface return TOK_INTERFACE;
-flags return TOK_FLAGS;
+ /* class member terminals */
-type return TOK_TYPE;
+class return TOK_CLASS;
private return TOK_PRIVATE;
internal return TOK_INTERNAL;
+flags return TOK_FLAGS;
+
+type return TOK_TYPE;
+
unshared return TOK_UNSHARED;
shared return TOK_SHARED;
property return TOK_PROPERTY;
-operation return TOK_OPERATION;
+ /* implementation terminals */
+
+init return TOK_INIT;
-api return TOK_API;
+fini return TOK_FINI;
+
+method return TOK_METHOD;
getter return TOK_GETTER;
setter return TOK_SETTER;
+ /* other terminals */
+
+{dblcolon} return TOK_DBLCOLON;
+
{cblockopen} BEGIN(cblock);
{identifier} {
@@ -140,7 +153,7 @@ setter return TOK_SETTER;
{multicomment} /* nothing */
-{poundsign}include BEGIN(incl);
+{poundsign}include BEGIN(incl);
{other} return (int) yytext[0];
@@ -151,7 +164,7 @@ setter return TOK_SETTER;
<cblock>\% yylval->text = strdup(yytext); return TOK_CCODE_LITERAL;
-<incl>[ \t]*\" /* eat the whitespace and open quotes */
+<incl>[ \t]*\" /* eat the whitespace and open quotes */
<incl>[^\t\n\"]+ {
/* got the include file name */
diff --git a/src/nsgenbind-parser.y b/src/nsgenbind-parser.y
index b37ab9d..c8e5154 100644
--- a/src/nsgenbind-parser.y
+++ b/src/nsgenbind-parser.y
@@ -10,6 +10,12 @@
#include <stdio.h>
#include <string.h>
+#define YYFPRINTF genbind_fprintf
+#define YY_LOCATION_PRINT(File, Loc) \
+ genbind_fprintf(File, "%d.%d-%d.%d", \
+ (Loc).first_line, (Loc).first_column, \
+ (Loc).last_line, (Loc).last_column)
+
#include "nsgenbind-parser.h"
#include "nsgenbind-lexer.h"
#include "webidl-ast.h"
@@ -17,7 +23,9 @@
char *errtxt;
- static void nsgenbind_error(YYLTYPE *locp, struct genbind_node **genbind_ast, const char *str)
+static void nsgenbind_error(YYLTYPE *locp,
+ struct genbind_node **genbind_ast,
+ const char *str)
{
locp = locp;
genbind_ast = genbind_ast;
@@ -37,31 +45,36 @@ char *errtxt;
%union
{
- char* text;
+ char *text;
struct genbind_node *node;
long value;
}
-%token TOK_IDLFILE
-%token TOK_HDR_COMMENT
-%token TOK_PREAMBLE
-%token TOK_PROLOGUE;
-%token TOK_EPILOGUE;
-
-%token TOK_API
%token TOK_BINDING
-%token TOK_OPERATION
-%token TOK_GETTER
-%token TOK_SETTER
-%token TOK_INTERFACE
-%token TOK_FLAGS
-%token TOK_TYPE
+%token TOK_WEBIDL
+%token TOK_PREFACE
+%token TOK_PROLOGUE
+%token TOK_EPILOGUE
+%token TOK_POSTFACE
+
+%token TOK_CLASS
%token TOK_PRIVATE
%token TOK_INTERNAL
+%token TOK_FLAGS
+%token TOK_TYPE
%token TOK_UNSHARED
%token TOK_SHARED
%token TOK_PROPERTY
+ /* method types */
+%token TOK_INIT
+%token TOK_FINI
+%token TOK_METHOD
+%token TOK_GETTER
+%token TOK_SETTER
+
+%token TOK_DBLCOLON
+
%token <text> TOK_IDENTIFIER
%token <text> TOK_STRING_LITERAL
%token <text> TOK_CCODE_LITERAL
@@ -73,28 +86,30 @@ char *errtxt;
%type <node> Statement
%type <node> Statements
-%type <node> IdlFile
-%type <node> Preamble
-%type <node> Prologue
-%type <node> Epilogue
-%type <node> HdrComment
-%type <node> Strings
%type <node> Binding
%type <node> BindingArgs
%type <node> BindingArg
+%type <node> Class
+%type <node> ClassArgs
+%type <node> ClassArg
+%type <node> ClassFlag
+%type <node> ClassFlags
+
+%type <node> Method
+%type <node> MethodDeclarator
+%type <value> MethodType
+
+%type <node> WebIDL
+%type <node> Preface
+%type <node> Prologue
+%type <node> Epilogue
+%type <node> Postface
%type <node> Private
%type <node> Internal
-%type <node> Interface
-%type <node> InterfaceArgs
-%type <node> InterfaceArg
-%type <node> InterfaceFlags
%type <node> Property
-%type <node> Operation
-%type <node> Api
-%type <node> Getter
-%type <node> Setter
-
+%type <node> ParameterList
+%type <node> TypeIdent
%%
@@ -126,68 +141,77 @@ Statements
Statement
:
- IdlFile
- |
- HdrComment
- |
- Preamble
- |
- Prologue
- |
- Epilogue
- |
Binding
|
- Operation
- |
- Api
+ Class
|
- Getter
- |
- Setter
+ Method
;
- /* [3] load a web IDL file */
-IdlFile
- :
- TOK_IDLFILE TOK_STRING_LITERAL ';'
+Binding
+ :
+ TOK_BINDING TOK_IDENTIFIER '{' BindingArgs '}'
{
- $$ = genbind_new_node(GENBIND_NODE_TYPE_WEBIDLFILE, NULL, $2);
+ $$ = genbind_new_node(GENBIND_NODE_TYPE_BINDING,
+ NULL,
+ genbind_new_node(GENBIND_NODE_TYPE_TYPE, $4, $2));
}
;
-HdrComment
- :
- TOK_HDR_COMMENT Strings ';'
+BindingArgs
+ :
+ BindingArg
+ |
+ BindingArgs BindingArg
{
- $$ = genbind_new_node(GENBIND_NODE_TYPE_HDRCOMMENT, NULL, $2);
+ $$ = genbind_node_link($2, $1);
}
;
-Strings
+BindingArg
:
- TOK_STRING_LITERAL
+ WebIDL
+ |
+ Preface
+ |
+ Prologue
+ |
+ Epilogue
+ |
+ Postface
+ ;
+
+ /* [3] a web IDL file specifier */
+WebIDL
+ :
+ TOK_WEBIDL TOK_STRING_LITERAL ';'
{
- $$ = genbind_new_node(GENBIND_NODE_TYPE_STRING, NULL, $1);
+ $$ = genbind_new_node(GENBIND_NODE_TYPE_WEBIDL, NULL, $2);
}
- |
- Strings TOK_STRING_LITERAL
+ ;
+
+
+ /* type and identifier of a variable */
+TypeIdent
+ :
+ TOK_STRING_LITERAL TOK_IDENTIFIER
{
- $$ = genbind_new_node(GENBIND_NODE_TYPE_STRING, $1, $2);
+ $$ = genbind_new_node(GENBIND_NODE_TYPE_IDENT,
+ genbind_new_node(GENBIND_NODE_TYPE_TYPE, NULL, $1), $2);
}
;
-Preamble
+Preface
:
- TOK_PREAMBLE CBlock
+ TOK_PREFACE CBlock ';'
{
- $$ = genbind_new_node(GENBIND_NODE_TYPE_PREAMBLE, NULL, $2);
+ $$ = genbind_new_node(GENBIND_NODE_TYPE_PREFACE, NULL, $2);
}
;
Prologue
:
- TOK_PROLOGUE CBlock
+ TOK_PROLOGUE CBlock ';'
{
$$ = genbind_new_node(GENBIND_NODE_TYPE_PROLOGUE, NULL, $2);
}
@@ -195,173 +219,196 @@ Prologue
Epilogue
:
- TOK_EPILOGUE CBlock
+ TOK_EPILOGUE CBlock ';'
{
$$ = genbind_new_node(GENBIND_NODE_TYPE_EPILOGUE, NULL, $2);
}
;
+Postface
+ :
+ TOK_POSTFACE CBlock ';'
+ {
+ $$ = genbind_new_node(GENBIND_NODE_TYPE_POSTFACE, NULL, $2);
+ }
+ ;
+
CBlock
- :
+ :
TOK_CCODE_LITERAL
- |
- CBlock TOK_CCODE_LITERAL
+ |
+ CBlock TOK_CCODE_LITERAL
{
$$ = genbind_strapp($1, $2);
}
;
-Operation
+MethodType
:
- TOK_OPERATION TOK_IDENTIFIER CBlock
+ TOK_INIT
{
- $$ = genbind_new_node(GENBIND_NODE_TYPE_OPERATION,
- NULL,
- genbind_new_node(GENBIND_NODE_TYPE_IDENT,
- genbind_new_node(GENBIND_NODE_TYPE_CBLOCK,
- NULL,
- $3),
- $2));
+ $$ = GENBIND_METHOD_TYPE_INIT;
}
+ |
+ TOK_FINI
+ {
+ $$ = GENBIND_METHOD_TYPE_FINI;
+ }
+ |
+ TOK_METHOD
+ {
+ $$ = GENBIND_METHOD_TYPE_METHOD;
+ }
+ |
+ TOK_GETTER
+ {
+ $$ = GENBIND_METHOD_TYPE_GETTER;
+ }
+ |
+ TOK_SETTER
+ {
+ $$ = GENBIND_METHOD_TYPE_SETTER;
+ }
+ ;
-Api
+ParameterList
:
- TOK_API TOK_IDENTIFIER CBlock
+ TypeIdent
+ {
+ $$ = genbind_new_node(GENBIND_NODE_TYPE_PARAMETER, NULL, $1);
+ }
+ |
+ ParameterList ',' TypeIdent
{
- $$ = genbind_new_node(GENBIND_NODE_TYPE_API,
- NULL,
- genbind_new_node(GENBIND_NODE_TYPE_IDENT,
- genbind_new_node(GENBIND_NODE_TYPE_CBLOCK,
- NULL,
- $3),
- $2));
+ $$ = genbind_node_link($3, $1);
}
+ ;
-Getter
+MethodDeclarator
:
- TOK_GETTER TOK_IDENTIFIER CBlock
+ TOK_IDENTIFIER TOK_DBLCOLON TOK_IDENTIFIER '(' ParameterList ')'
{
- $$ = genbind_new_node(GENBIND_NODE_TYPE_GETTER,
- NULL,
- genbind_new_node(GENBIND_NODE_TYPE_IDENT,
- genbind_new_node(GENBIND_NODE_TYPE_CBLOCK,
- NULL,
- $3),
- $2));
+ $$ = genbind_new_node(GENBIND_NODE_TYPE_CLASS,
+ genbind_new_node(GENBIND_NODE_TYPE_IDENT,
+ $5,
+ $3),
+ genbind_new_node(GENBIND_NODE_TYPE_IDENT,
+ NULL,
+ $1));
}
+ |
+ TOK_IDENTIFIER TOK_DBLCOLON TOK_IDENTIFIER '(' ')'
+ {
+ $$ = genbind_new_node(GENBIND_NODE_TYPE_CLASS,
+ genbind_new_node(GENBIND_NODE_TYPE_IDENT,
+ NULL,
+ $3),
+ genbind_new_node(GENBIND_NODE_TYPE_IDENT,
+ NULL,
+ $1));
+ }
+ |
+ TOK_IDENTIFIER '(' ParameterList ')'
+ {
+ $$ = genbind_new_node(GENBIND_NODE_TYPE_CLASS,
+ $3,
+ genbind_new_node(GENBIND_NODE_TYPE_IDENT,
+ NULL,
+ $1));
+ }
+ |
+ TOK_IDENTIFIER '(' ')'
+ {
+ $$ = genbind_new_node(GENBIND_NODE_TYPE_CLASS, NULL,
+ genbind_new_node(GENBIND_NODE_TYPE_IDENT,
+ NULL,
+ $1));
+ }
+ ;
-Setter
+Method
:
- TOK_SETTER TOK_IDENTIFIER CBlock
+ MethodType MethodDeclarator CBlock
{
- $$ = genbind_new_node(GENBIND_NODE_TYPE_SETTER,
- NULL,
- genbind_new_node(GENBIND_NODE_TYPE_IDENT,
- genbind_new_node(GENBIND_NODE_TYPE_CBLOCK,
- NULL,
- $3),
- $2));
+ $$ = genbind_new_node(GENBIND_NODE_TYPE_METHOD, NULL,
+ genbind_new_node(GENBIND_NODE_TYPE_METHOD_TYPE,
+ genbind_new_node(GENBIND_NODE_TYPE_CDATA,
+ $2, $3),
+ (void *)$1));
}
-Binding
+
+Class
:
- TOK_BINDING TOK_IDENTIFIER '{' BindingArgs '}'
+ TOK_CLASS TOK_IDENTIFIER '{' ClassArgs '}'
{
- $$ = genbind_new_node(GENBIND_NODE_TYPE_BINDING,
- NULL,
- genbind_new_node(GENBIND_NODE_TYPE_TYPE, $4, $2));
+ $$ = genbind_new_node(GENBIND_NODE_TYPE_CLASS, NULL,
+ genbind_new_node(GENBIND_NODE_TYPE_IDENT, $4, $2));
}
;
-BindingArgs
+ClassArgs
:
- BindingArg
+ ClassArg
|
- BindingArgs BindingArg
+ ClassArgs ClassArg
{
- $$ = genbind_node_link($2, $1);
+ $$ = genbind_node_link($2, $1);
}
;
-BindingArg
- :
+ClassArg
+ :
Private
|
Internal
|
- Interface
- |
Property
+ |
+ ClassFlag
+ |
+ Preface
+ |
+ Prologue
+ |
+ Epilogue
+ |
+ Postface
;
+
Private
:
- TOK_PRIVATE TOK_STRING_LITERAL TOK_IDENTIFIER ';'
+ TOK_PRIVATE TypeIdent ';'
{
- $$ = genbind_new_node(GENBIND_NODE_TYPE_BINDING_PRIVATE, NULL,
- genbind_new_node(GENBIND_NODE_TYPE_IDENT,
- genbind_new_node(GENBIND_NODE_TYPE_STRING, NULL, $2), $3));
+ $$ = genbind_new_node(GENBIND_NODE_TYPE_PRIVATE, NULL, $2);
}
;
Internal
:
- TOK_INTERNAL TOK_STRING_LITERAL TOK_IDENTIFIER ';'
+ TOK_INTERNAL TypeIdent ';'
{
- $$ = genbind_new_node(GENBIND_NODE_TYPE_BINDING_INTERNAL, NULL,
- genbind_new_node(GENBIND_NODE_TYPE_IDENT,
- genbind_new_node(GENBIND_NODE_TYPE_STRING, NULL, $2), $3));
+ $$ = genbind_new_node(GENBIND_NODE_TYPE_INTERNAL, NULL, $2);
}
;
-Interface
- :
- TOK_INTERFACE TOK_IDENTIFIER ';'
- {
- $$ = genbind_new_node(GENBIND_NODE_TYPE_BINDING_INTERFACE, NULL,
- genbind_new_node(GENBIND_NODE_TYPE_IDENT, NULL, $2));
- }
- |
- TOK_INTERFACE TOK_IDENTIFIER '{' '}'
- {
- $$ = genbind_new_node(GENBIND_NODE_TYPE_BINDING_INTERFACE, NULL,
- genbind_new_node(GENBIND_NODE_TYPE_IDENT, NULL, $2));
- }
- |
- TOK_INTERFACE TOK_IDENTIFIER '{' InterfaceArgs '}'
- {
- $$ = genbind_new_node(GENBIND_NODE_TYPE_BINDING_INTERFACE,
- NULL,
- genbind_new_node(GENBIND_NODE_TYPE_IDENT, $4, $2));
- }
- ;
-
-InterfaceArgs
+ClassFlag
:
- InterfaceArg
- |
- InterfaceArgs InterfaceArg
- {
- $$ = genbind_node_link($2, $1);
- }
- ;
-
-InterfaceArg
- :
- TOK_FLAGS InterfaceFlags ';'
+ TOK_FLAGS ClassFlags ';'
{
- $$ = genbind_new_node(GENBIND_NODE_TYPE_BINDING_INTERFACE_FLAGS, NULL, $2);
+ $$ = genbind_new_node(GENBIND_NODE_TYPE_FLAGS, NULL, $2);
}
;
-InterfaceFlags
+ClassFlags
:
TOK_IDENTIFIER
{
$$ = genbind_new_node(GENBIND_NODE_TYPE_IDENT, NULL, $1);
}
|
- InterfaceFlags ',' TOK_IDENTIFIER
+ ClassFlags ',' TOK_IDENTIFIER
{
$$ = genbind_new_node(GENBIND_NODE_TYPE_IDENT, $1, $3);
}
@@ -371,13 +418,12 @@ Property
:
TOK_PROPERTY Modifiers TOK_IDENTIFIER ';'
{
- $$ = genbind_new_node(GENBIND_NODE_TYPE_BINDING_PROPERTY,
- NULL,
- genbind_new_node(GENBIND_NODE_TYPE_MODIFIER,
- genbind_new_node(GENBIND_NODE_TYPE_IDENT,
- NULL,
- $3),
- (void *)$2));
+ $$ = genbind_new_node(GENBIND_NODE_TYPE_PROPERTY, NULL,
+ genbind_new_node(GENBIND_NODE_TYPE_MODIFIER,
+ genbind_new_node(GENBIND_NODE_TYPE_IDENT,
+ NULL,
+ $3),
+ (void *)$2));
}
;
diff --git a/src/nsgenbind.c b/src/nsgenbind.c
index d81f30f..3174fa0 100644
--- a/src/nsgenbind.c
+++ b/src/nsgenbind.c
@@ -22,201 +22,173 @@ struct options *options;
static struct options* process_cmdline(int argc, char **argv)
{
- int opt;
+ int opt;
- options = calloc(1,sizeof(struct options));
- if (options == NULL) {
- fprintf(stderr, "Allocation error\n");
- return NULL;
- }
+ options = calloc(1,sizeof(struct options));
+ if (options == NULL) {
+ fprintf(stderr, "Allocation error\n");
+ return NULL;
+ }
- while ((opt = getopt(argc, argv, "vgDW::d:I:o:h:")) != -1) {
- switch (opt) {
- case 'I':
- options->idlpath = strdup(optarg);
- break;
+ while ((opt = getopt(argc, argv, "vgDW::I:")) != -1) {
+ switch (opt) {
+ case 'I':
+ options->idlpath = strdup(optarg);
+ break;
- case 'o':
- options->outfilename = strdup(optarg);
- break;
+ case 'v':
+ options->verbose = true;
+ break;
- case 'h':
- options->hdrfilename = strdup(optarg);
- break;
+ case 'D':
+ options->debug = true;
+ break;
- case 'd':
- options->depfilename = strdup(optarg);
- break;
+ case 'g':
+ options->dbglog = true;
+ break;
- case 'v':
- options->verbose = true;
- break;
+ case 'W':
+ options->warnings = 1; /* warning flags */
+ break;
- case 'D':
- options->debug = true;
- break;
+ default: /* '?' */
+ fprintf(stderr,
+ "Usage: %s [-v] [-g] [-D] [-W] [-I idlpath] inputfile outputdir\n",
+ argv[0]);
+ free(options);
+ return NULL;
- case 'g':
- options->dbglog = true;
- break;
+ }
+ }
- case 'W':
- options->warnings = 1; /* warning flags */
- break;
+ if (optind > (argc - 2)) {
+ fprintf(stderr,
+ "Error: expected input filename and output directory\n");
+ free(options);
+ return NULL;
+ }
- default: /* '?' */
- fprintf(stderr,
- "Usage: %s [-v] [-g] [-D] [-W] [-d depfilename] [-I idlpath] [-o filename] [-h headerfile] inputfile\n",
- argv[0]);
- free(options);
- return NULL;
+ options->infilename = strdup(argv[optind]);
- }
- }
+ options->outdirname = strdup(argv[optind + 1]);
- if (optind >= argc) {
- fprintf(stderr, "Error: expected input filename\n");
- free(options);
- return NULL;
- }
-
- options->infilename = strdup(argv[optind]);
-
- return options;
+ return options;
}
static int generate_binding(struct genbind_node *binding_node, void *ctx)
{
- struct genbind_node *genbind_root = ctx;
- char *type;
- int res = 10;
-
- type = genbind_node_gettext(
- genbind_node_find_type(
- genbind_node_getnode(binding_node),
- NULL,
- GENBIND_NODE_TYPE_TYPE));
-
- if (strcmp(type, "jsapi_libdom") == 0) {
- res = jsapi_libdom_output(options, genbind_root, binding_node);
- } else {
- fprintf(stderr, "Error: unsupported binding type \"%s\"\n", type);
- }
-
- return res;
+ struct genbind_node *genbind_root = ctx;
+ char *type;
+ int res = 10;
+
+ type = genbind_node_gettext(
+ genbind_node_find_type(
+ genbind_node_getnode(binding_node),
+ NULL,
+ GENBIND_NODE_TYPE_TYPE));
+
+ if (strcmp(type, "jsapi_libdom") == 0) {
+ res = jsapi_libdom_output(options, genbind_root, binding_node);
+ } else {
+ fprintf(stderr, "Error: unsupported binding type \"%s\"\n", type);
+ }
+
+ return res;
+}
+
+enum bindingtype_e {
+ BINDINGTYPE_UNKNOWN,
+ BINDINGTYPE_JSAPI_LIBDOM,
+ BINDINGTYPE_DUK_LIBDOM,
+};
+
+/**
+ * get the type of binding
+ */
+static enum bindingtype_e genbind_get_type(struct genbind_node *node)
+{
+ struct genbind_node *binding_node;
+ const char *binding_type;
+
+ binding_node = genbind_node_find_type(node,
+ NULL,
+ GENBIND_NODE_TYPE_BINDING);
+ if (binding_node == NULL) {
+ /* binding entry is missing which is invalid */
+ return BINDINGTYPE_UNKNOWN;
+ }
+
+ binding_type = genbind_node_gettext(
+ genbind_node_find_type(
+ genbind_node_getnode(binding_node),
+ NULL,
+ GENBIND_NODE_TYPE_TYPE));
+ if (binding_type == NULL) {
+ fprintf(stderr, "Error: missing binding type\n");
+ return BINDINGTYPE_UNKNOWN;
+ }
+
+ if (strcmp(binding_type, "jsapi_libdom") == 0) {
+ return BINDINGTYPE_JSAPI_LIBDOM;
+ }
+
+ if (strcmp(binding_type, "duk_libdom") == 0) {
+ return BINDINGTYPE_DUK_LIBDOM;
+ }
+
+ fprintf(stderr, "Error: unsupported binding type \"%s\"\n", binding_type);
+
+ return BINDINGTYPE_UNKNOWN;
}
int main(int argc, char **argv)
{
- int res;
- struct genbind_node *genbind_root;
-
- options = process_cmdline(argc, argv);
- if (options == NULL) {
- return 1; /* bad commandline */
- }
-
- if (options->verbose &&
- (options->outfilename == NULL)) {
- fprintf(stderr,
- "Error: output to stdout with verbose logging would fail\n");
- return 2;
- }
-
- if (options->depfilename != NULL &&
- options->outfilename == NULL) {
- fprintf(stderr,
- "Error: output to stdout with dep generation would fail\n");
- return 3;
- }
-
- if (options->depfilename != NULL &&
- options->infilename == NULL) {
- fprintf(stderr,
- "Error: input from stdin with dep generation would fail\n");
- return 3;
- }
-
- /* open dependancy file */
- if (options->depfilename != NULL) {
- options->depfilehandle = fopen(options->depfilename, "w");
- if (options->depfilehandle == NULL) {
- fprintf(stderr,
- "Error: unable to open dep file\n");
- return 4;
- }
- fprintf(options->depfilehandle,
- "%s %s :", options->depfilename,
- options->outfilename);
- }
-
- /* parse input and generate dependancy */
- res = genbind_parsefile(options->infilename, &genbind_root);
- if (res != 0) {
- fprintf(stderr, "Error: parse failed with code %d\n", res);
- return res;
- }
-
- /* dependancy generation complete */
- if (options->depfilehandle != NULL) {
- fputc('\n', options->depfilehandle);
- fclose(options->depfilehandle);
- }
-
-
- /* open output file */
- if (options->outfilename == NULL) {
- options->outfilehandle = stdout;
- } else {
- options->outfilehandle = fopen(options->outfilename, "w");
- }
- if (options->outfilehandle == NULL) {
- fprintf(stderr, "Error opening source output %s: %s\n",
- options->outfilename,
- strerror(errno));
- return 5;
- }
-
- /* open output header file if required */
- if (options->hdrfilename != NULL) {
- options->hdrfilehandle = fopen(options->hdrfilename, "w");
- if (options->hdrfilehandle == NULL) {
- fprintf(stderr, "Error opening header output %s: %s\n",
- options->hdrfilename,
- strerror(errno));
- /* close and unlink output file */
- fclose(options->outfilehandle);
- if (options->outfilename != NULL) {
- unlink(options->outfilename);
- }
- return 6;
- }
- } else {
- options->hdrfilehandle = NULL;
- }
-
- /* dump the AST */
- if (options->verbose) {
- genbind_ast_dump(genbind_root, 0);
- }
-
- /* generate output for each binding */
- res = genbind_node_foreach_type(genbind_root,
- GENBIND_NODE_TYPE_BINDING,
- generate_binding,
- genbind_root);
- if (res != 0) {
- fprintf(stderr, "Error: output failed with code %d\n", res);
- if (options->outfilename != NULL) {
- unlink(options->outfilename);
- }
- if (options->hdrfilename != NULL) {
- unlink(options->hdrfilename);
- }
- return res;
- }
-
-
- return 0;
+ int res;
+ struct genbind_node *genbind_root;
+ enum bindingtype_e bindingtype;
+
+ options = process_cmdline(argc, argv);
+ if (options == NULL) {
+ return 1; /* bad commandline */
+ }
+
+ /* parse input and generate dependancy */
+ res = genbind_parsefile(options->infilename, &genbind_root);
+ if (res != 0) {
+ fprintf(stderr, "Error: parse failed with code %d\n", res);
+ return res;
+ }
+
+ /* dump the AST */
+ genbind_dump_ast(genbind_root);
+
+ /* get bindingtype */
+ bindingtype = genbind_get_type(genbind_root);
+ if (bindingtype == BINDINGTYPE_UNKNOWN) {
+ return 3;
+ }
+
+#if 0
+ genbind_load_idl(genbind_root);
+
+ /* generate output for each binding */
+ res = genbind_node_foreach_type(genbind_root,
+ GENBIND_NODE_TYPE_BINDING,
+ generate_binding,
+ genbind_root);
+ if (res != 0) {
+ fprintf(stderr, "Error: output failed with code %d\n", res);
+ if (options->outfilename != NULL) {
+ unlink(options->outfilename);
+ }
+ if (options->hdrfilename != NULL) {
+ unlink(options->hdrfilename);
+ }
+ return res;
+ }
+
+#endif
+ return 0;
}
diff --git a/src/options.h b/src/options.h
index cbac9a3..68a4bc1 100644
--- a/src/options.h
+++ b/src/options.h
@@ -12,16 +12,11 @@
/** global options */
struct options {
char *infilename; /**< binding source */
-
- char *outfilename; /**< output source file */
- FILE *outfilehandle; /**< output file handle */
-
- char *hdrfilename; /**< output header file */
- FILE *hdrfilehandle; /**< output file handle */
-
- char *depfilename; /**< dependancy output*/
- FILE *depfilehandle; /**< dependancy file handle */
-
+ char *outdirname; /**< output directory */
+FILE *hdrfilehandle;
+char *hdrfilename;
+char *outfilename;
+FILE *outfilehandle;
char *idlpath; /**< path to IDL files */
bool verbose; /**< verbose processing */
diff --git a/src/utils.c b/src/utils.c
new file mode 100644
index 0000000..7bab058
--- /dev/null
+++ b/src/utils.c
@@ -0,0 +1,52 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdbool.h>
+#include <errno.h>
+#include <stdlib.h>
+
+#include "options.h"
+#include "utils.h"
+
+FILE *genb_fopen(const char *fname, const char *mode)
+{
+ char *fpath;
+ int fpathl;
+ FILE *filef;
+
+ fpathl = strlen(options->outdirname) + strlen(fname) + 2;
+ fpath = malloc(fpathl);
+ snprintf(fpath, fpathl, "%s/%s", options->outdirname, fname);
+
+ filef = fopen(fpath, mode);
+ if (filef == NULL) {
+ fprintf(stderr, "Error: unable to open file %s (%s)\n",
+ fpath, strerror(errno));
+ free(fpath);
+ return NULL;
+ }
+ free(fpath);
+
+ return filef;
+}
+
+#ifdef NEED_STRNDUP
+
+char *strndup(const char *s, size_t n)
+{
+ size_t len;
+ char *s2;
+
+ for (len = 0; len != n && s[len]; len++)
+ continue;
+
+ s2 = malloc(len + 1);
+ if (!s2)
+ return 0;
+
+ memcpy(s2, s, len);
+ s2[len] = 0;
+ return s2;
+}
+
+#endif
+
diff --git a/src/utils.h b/src/utils.h
new file mode 100644
index 0000000..98a4c6b
--- /dev/null
+++ b/src/utils.h
@@ -0,0 +1,21 @@
+/* utility helpers
+ *
+ * This file is part of nsnsgenbind.
+ * Licensed under the MIT License,
+ * http://www.opensource.org/licenses/mit-license.php
+ * Copyright 2015 Vincent Sanders <vince@netsurf-browser.org>
+ */
+
+#ifndef nsgenbind_utils_h
+#define nsgenbind_utils_h
+
+FILE *genb_fopen(const char *fname, const char *mode);
+
+#ifdef _WIN32
+#define NEED_STRNDUP 1
+char *strndup(const char *s, size_t n);
+#endif
+
+#define SLEN(x) (sizeof((x)) - 1)
+
+#endif