From 1288d8c535edd2ce29eebdc4acca6b2beab89841 Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Tue, 21 Jul 2015 23:48:45 +0100 Subject: Change binding grammar to new approach. --- src/Makefile | 3 +- src/nsgenbind-ast.c | 759 ++++++++++++++++++++++++++----------------------- src/nsgenbind-ast.h | 113 ++++---- src/nsgenbind-lexer.l | 39 ++- src/nsgenbind-parser.y | 386 ++++++++++++++----------- src/nsgenbind.c | 324 ++++++++++----------- src/options.h | 15 +- src/utils.c | 52 ++++ src/utils.h | 21 ++ 9 files changed, 937 insertions(+), 775 deletions(-) create mode 100644 src/utils.c create mode 100644 src/utils.h (limited to 'src') 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 #include #include +#include +#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; \% yylval->text = strdup(yytext); return TOK_CCODE_LITERAL; -[ \t]*\" /* eat the whitespace and open quotes */ +[ \t]*\" /* eat the whitespace and open quotes */ [^\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 #include +#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 TOK_IDENTIFIER %token TOK_STRING_LITERAL %token TOK_CCODE_LITERAL @@ -73,28 +86,30 @@ char *errtxt; %type Statement %type Statements -%type IdlFile -%type Preamble -%type Prologue -%type Epilogue -%type HdrComment -%type Strings %type Binding %type BindingArgs %type BindingArg +%type Class +%type ClassArgs +%type ClassArg +%type ClassFlag +%type ClassFlags + +%type Method +%type MethodDeclarator +%type MethodType + +%type WebIDL +%type Preface +%type Prologue +%type Epilogue +%type Postface %type Private %type Internal -%type Interface -%type InterfaceArgs -%type InterfaceArg -%type InterfaceFlags %type Property -%type Operation -%type Api -%type Getter -%type Setter - +%type ParameterList +%type 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 +#include +#include +#include +#include + +#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 + */ + +#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 -- cgit v1.2.3