From c1db25526a6990263e9703634401178975cf9d61 Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Thu, 6 Sep 2012 02:59:31 +0100 Subject: initial output generation --- src/Makefile | 2 +- src/genjsbind-lexer.l | 4 ++ src/genjsbind-parser.y | 47 ++++++++++++++++++-- src/genjsbind.c | 88 ++++++++++--------------------------- src/genjsbind.h | 11 ++++- src/jsapi-binding.c | 66 ++++++++++++++++++++++++++++ src/jsapi-binding.h | 4 ++ src/webidl-ast.c | 71 ++++++++++++++++++++++++++++++ src/webidl-ast.h | 28 +++++++++++- test/data/bindings/htmldocument.bnd | 6 +++ 10 files changed, 254 insertions(+), 73 deletions(-) create mode 100644 src/jsapi-binding.c create mode 100644 src/jsapi-binding.h create mode 100644 src/webidl-ast.c diff --git a/src/Makefile b/src/Makefile index e2eb873..62fb23b 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,7 +1,7 @@ CFLAGS := $(CFLAGS) -I$(BUILDDIR) -Isrc/ -g # Sources in this directory -DIR_SOURCES := genjsbind.c +DIR_SOURCES := genjsbind.c webidl-ast.c jsapi-binding.c SOURCES := $(SOURCES) $(BUILDDIR)/genjsbind-parser.c $(BUILDDIR)/genjsbind-lexer.c $(BUILDDIR)/webidl-parser.c $(BUILDDIR)/webidl-lexer.c diff --git a/src/genjsbind-lexer.l b/src/genjsbind-lexer.l index e976a8f..ae458fe 100644 --- a/src/genjsbind-lexer.l +++ b/src/genjsbind-lexer.l @@ -41,6 +41,10 @@ other [^\t\n\r 0-9A-Z_a-z] webidlfile return TOK_IDLFILE; +hdrcomment return TOK_HDR_COMMENT; + +interface return TOK_INTERFACE; + \"{quotedstring}*\" yylval->text = strndup(yytext + 1,strlen(yytext+1) - 1 ); return TOK_STRING_LITERAL; {multicomment} /* nothing */ diff --git a/src/genjsbind-parser.y b/src/genjsbind-parser.y index 5c5bed5..48ea1d2 100644 --- a/src/genjsbind-parser.y +++ b/src/genjsbind-parser.y @@ -10,7 +10,8 @@ #include "genjsbind-parser.h" #include "genjsbind-lexer.h" -#include "genjsbind.h" +#include "webidl-ast.h" +#include "jsapi-binding.h" static void genjsbind_error(const char *str) { @@ -35,29 +36,67 @@ int genjsbind_wrap() } %token TOK_IDLFILE +%token TOK_HDR_COMMENT +%token TOK_INTERFACE -%token TOK_STRING_LITERAL +%token TOK_STRING_LITERAL + +%type Strings %% /* [1] start with Statements */ Statements : Statement - | Statement Statements + | Statements Statement ; Statement : IdlFile + | HdrComment + | Interface ; /* [3] load a web IDL file */ IdlFile : TOK_IDLFILE TOK_STRING_LITERAL ';' { - if (loadwebidl($2) != 0) { + if (webidl_parsefile($2) != 0) { YYABORT; } } ; +HdrComment + : TOK_HDR_COMMENT Strings ';' + { + genjsbind_header_comment($2); + } + ; + +Strings + : TOK_STRING_LITERAL + { + $$ = $1; + } + | Strings TOK_STRING_LITERAL + { + char *fullstr; + int fulllen; + fulllen = strlen($1) + strlen($2) + 2; + fullstr = malloc(fulllen); + snprintf(fullstr, fulllen, "%s\n%s", $1, $2); + free($1); + free($2); + $$ = fullstr; + } + ; + +Interface + : TOK_INTERFACE TOK_STRING_LITERAL ';' + { + genjsbind_output_interface($2); + } + ; + %% diff --git a/src/genjsbind.c b/src/genjsbind.c index 89d2fb0..fcdc944 100644 --- a/src/genjsbind.c +++ b/src/genjsbind.c @@ -9,75 +9,16 @@ #include "webidl-ast.h" #include "webidl-parser.h" #include "genjsbind-parser.h" +#include "jsapi-binding.h" #include "genjsbind.h" -extern int webidl_debug; -extern int webidl__flex_debug; -extern void webidl_restart(FILE*); -extern int webidl_parse(void); - extern int genjsbind_debug; extern int genjsbind__flex_debug; extern void genjsbind_restart(FILE*); extern int genjsbind_parse(void); -struct options { - char *outfilename; - char *infilename; - char *idlpath; - bool verbose; - bool debug; -}; - struct options *options; -static FILE *idlopen(const char *filename) -{ - FILE *idlfile; - - if (options->idlpath == NULL) { - if (options->verbose) { - printf("Opening IDL file %s\n", filename); - } - idlfile = fopen(filename, "r"); - } else { - char *fullname; - int fulllen = strlen(options->idlpath) + strlen(filename) + 2; - fullname = malloc(fulllen); - snprintf(fullname, fulllen, "%s/%s", options->idlpath, filename); - if (options->verbose) { - printf("Opening IDL file %s\n", fullname); - } - idlfile = fopen(fullname, "r"); - free(fullname); - } - return idlfile; -} - -int loadwebidl(char *filename) -{ - /* set flex to read from file */ - FILE *idlfile; - idlfile = idlopen(filename); - if (!idlfile) { - fprintf(stderr, "Error opening %s: %s\n", - filename, - strerror(errno)); - return 2; - } - - if (options->debug) { - webidl_debug = 1; - webidl__flex_debug = 1; - } - - webidl_restart(idlfile); - - /* parse the file */ - return webidl_parse(); -} - - static struct options* process_cmdline(int argc, char **argv) { int opt; @@ -131,7 +72,7 @@ static struct options* process_cmdline(int argc, char **argv) int main(int argc, char **argv) { FILE *infile; - int parse_res; + int res; options = process_cmdline(argc, argv); if (options == NULL) { @@ -143,6 +84,12 @@ int main(int argc, char **argv) return 2; } + res = genjsbind_outputopen(options->outfilename); + if (res != 0) { + return res; + } + + /* open input file */ if ((options->infilename[0] == '-') && (options->infilename[1] == 0)) { if (options->verbose) { @@ -170,11 +117,20 @@ int main(int argc, char **argv) /* set flex to read from file */ genjsbind_restart(infile); - - parse_res = genjsbind_parse(); - if (parse_res) { - fprintf(stderr, "parse result was %d\n", parse_res); - return parse_res; + + /* initialise root node */ + webidl_root = webidl_new_node(WEBIDL_NODE_TYPE_ROOT); + + /* process binding */ + res = genjsbind_parse(); + + genjsbind_outputclose(); + + if (res != 0) { + fprintf(stderr, "Error parse failed with code %d\n", res); + return res; } + + return 0; } diff --git a/src/genjsbind.h b/src/genjsbind.h index 69d2f59..47f3c11 100644 --- a/src/genjsbind.h +++ b/src/genjsbind.h @@ -1 +1,10 @@ -extern int loadwebidl(char *filename); +struct options { + char *outfilename; + char *infilename; + char *idlpath; + bool verbose; + bool debug; +}; + +extern struct options *options; + diff --git a/src/jsapi-binding.c b/src/jsapi-binding.c new file mode 100644 index 0000000..51a0df7 --- /dev/null +++ b/src/jsapi-binding.c @@ -0,0 +1,66 @@ +#include +#include +#include +#include +#include + +#include "jsapi-binding.h" + +#define HDR_COMMENT_PREABLE "/* Generated by nsgenjsapi\n" + +static FILE *outfile = NULL; +static char *hdr_comments = NULL; +static bool hdr_comments_output = false; + +int genjsbind_outputopen(char *outfilename) +{ + /* open output file */ + if (outfilename == NULL) { + outfile = stdout; + } else { + outfile = fopen(outfilename, "w"); + } + + if (!outfile) { + fprintf(stderr, "Error opening output %s: %s\n", + outfilename, + strerror(errno)); + return 4; + } + + hdr_comments = strdup(HDR_COMMENT_PREABLE); + return 0; +} + +int genjsbind_outputclose() +{ + fclose(outfile); + return 0; +} + +int genjsbind_header_comment(char *comment) +{ + char *fullstr; + int fulllen; + fulllen = strlen(hdr_comments) + strlen(comment) + 2; + fullstr = malloc(fulllen); + snprintf(fullstr, fulllen, "%s\n%s", hdr_comments , comment); + free(hdr_comments); + free(comment); + hdr_comments = fullstr; + + if (hdr_comments_output) { + fprintf(stderr, "Warning: adding header comments after output already started\n"); + } + return 0; +} + +int genjsbind_output_interface(const char *interface) +{ + if (!hdr_comments_output) { + fprintf(outfile, "%s\n*/\n\n", hdr_comments); + hdr_comments_output = true; + } + fprintf(outfile, "/* interface %s */\n\n", interface); + return 0; +} diff --git a/src/jsapi-binding.h b/src/jsapi-binding.h new file mode 100644 index 0000000..ac7929c --- /dev/null +++ b/src/jsapi-binding.h @@ -0,0 +1,4 @@ +int genjsbind_outputopen(char *outfilename); +int genjsbind_outputclose(void); +int genjsbind_header_comment(char *); +int genjsbind_output_interface(const char *); diff --git a/src/webidl-ast.c b/src/webidl-ast.c new file mode 100644 index 0000000..b300383 --- /dev/null +++ b/src/webidl-ast.c @@ -0,0 +1,71 @@ +#include +#include +#include +#include +#include + +#include "webidl-ast.h" +#include "genjsbind.h" + +extern int webidl_debug; +extern int webidl__flex_debug; +extern void webidl_restart(FILE*); +extern int webidl_parse(void); + +struct webidl_node *webidl_root; + +struct webidl_node *webidl_new_node(enum webidl_node_type type) +{ + struct webidl_node *nnode; + nnode = calloc(1, sizeof(struct webidl_node)); + if (nnode != NULL) { + nnode->type = type; + } + return nnode; +} + +static FILE *idlopen(const char *filename) +{ + FILE *idlfile; + + if (options->idlpath == NULL) { + if (options->verbose) { + printf("Opening IDL file %s\n", filename); + } + idlfile = fopen(filename, "r"); + } else { + char *fullname; + int fulllen = strlen(options->idlpath) + strlen(filename) + 2; + fullname = malloc(fulllen); + snprintf(fullname, fulllen, "%s/%s", options->idlpath, filename); + if (options->verbose) { + printf("Opening IDL file %s\n", fullname); + } + idlfile = fopen(fullname, "r"); + free(fullname); + } + return idlfile; +} + +int webidl_parsefile(char *filename) +{ + /* set flex to read from file */ + FILE *idlfile; + idlfile = idlopen(filename); + if (!idlfile) { + fprintf(stderr, "Error opening %s: %s\n", + filename, + strerror(errno)); + return 2; + } + + if (options->debug) { + webidl_debug = 1; + webidl__flex_debug = 1; + } + + webidl_restart(idlfile); + + /* parse the file */ + return webidl_parse(); +} diff --git a/src/webidl-ast.h b/src/webidl-ast.h index f56c5d9..f49268a 100644 --- a/src/webidl-ast.h +++ b/src/webidl-ast.h @@ -1,4 +1,30 @@ +enum webidl_node_type { + WEBIDL_NODE_TYPE_ROOT, + WEBIDL_NODE_TYPE_INTERFACE, +}; + +struct webidl_ifmember { + char *name; +}; -struct ifmembers_s { +struct webidl_if { char *name; + struct webidl_ifmember* members; }; + + +struct webidl_node { + enum webidl_node_type type; + union { + struct webidl_node *nodes; + struct webidl_if interface; + } data; +}; + + +extern struct webidl_node *webidl_root; + +/** parse web idl file */ +int webidl_parsefile(char *filename); + +struct webidl_node *webidl_new_node(enum webidl_node_type type); diff --git a/test/data/bindings/htmldocument.bnd b/test/data/bindings/htmldocument.bnd index e531d05..d370be0 100644 --- a/test/data/bindings/htmldocument.bnd +++ b/test/data/bindings/htmldocument.bnd @@ -5,3 +5,9 @@ webidlfile "node.idl"; webidlfile "document.idl"; webidlfile "htmldocument.idl"; +hdrcomment "Part of NetSurf Project"; +hdrcomment "multi" + "line" + "comment"; + +interface "Document"; -- cgit v1.2.3