summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorVincent Sanders <vince@kyllikki.org>2012-09-06 02:59:31 +0100
committerVincent Sanders <vince@kyllikki.org>2012-09-06 02:59:31 +0100
commitc1db25526a6990263e9703634401178975cf9d61 (patch)
treeba737f0e32cfa287c5f4a746fa0679924adaf80a /src
parentda234bc3e4e44693a6464140d2dee91a948a6145 (diff)
downloadnsgenbind-c1db25526a6990263e9703634401178975cf9d61.tar.gz
nsgenbind-c1db25526a6990263e9703634401178975cf9d61.tar.bz2
initial output generation
Diffstat (limited to 'src')
-rw-r--r--src/Makefile2
-rw-r--r--src/genjsbind-lexer.l4
-rw-r--r--src/genjsbind-parser.y47
-rw-r--r--src/genjsbind.c88
-rw-r--r--src/genjsbind.h11
-rw-r--r--src/jsapi-binding.c66
-rw-r--r--src/jsapi-binding.h4
-rw-r--r--src/webidl-ast.c71
-rw-r--r--src/webidl-ast.h28
9 files changed, 248 insertions, 73 deletions
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 <text> TOK_STRING_LITERAL
+%token <text> TOK_STRING_LITERAL
+
+%type <text> 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 <stdio.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+
+#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 <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#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);