summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/genjsbind-lexer.l14
-rw-r--r--src/genjsbind-parser.y57
-rw-r--r--src/genjsbind.c62
-rw-r--r--src/jsapi-binding.c142
-rw-r--r--src/jsapi-binding.h7
-rw-r--r--src/options.h (renamed from src/genjsbind.h)0
-rw-r--r--src/webidl-ast.c2
-rw-r--r--test/data/bindings/htmldocument.bnd43
8 files changed, 218 insertions, 109 deletions
diff --git a/src/genjsbind-lexer.l b/src/genjsbind-lexer.l
index ae458fe..8364247 100644
--- a/src/genjsbind-lexer.l
+++ b/src/genjsbind-lexer.l
@@ -35,6 +35,12 @@ quotedstring [^\"\\\n\r]
other [^\t\n\r 0-9A-Z_a-z]
+cblockopen \[\[\[
+
+cblockclose \]\]\]
+
+%x cblock
+
%%
{whitespace} /* nothing */
@@ -45,6 +51,10 @@ hdrcomment return TOK_HDR_COMMENT;
interface return TOK_INTERFACE;
+preamble return TOK_PREAMBLE;
+
+{cblockopen} BEGIN(cblock);
+
\"{quotedstring}*\" yylval->text = strndup(yytext + 1,strlen(yytext+1) - 1 ); return TOK_STRING_LITERAL;
{multicomment} /* nothing */
@@ -53,4 +63,8 @@ interface return TOK_INTERFACE;
. /* nothing */
+<cblock>[^\]]* yylval->text = strdup(yytext); return TOK_CCODE_LITERAL;
+<cblock>{cblockclose} BEGIN(INITIAL);
+<cblock>\]+ yylval->text = strdup(yytext); return TOK_CCODE_LITERAL;
+
%%
diff --git a/src/genjsbind-parser.y b/src/genjsbind-parser.y
index 48ea1d2..8436034 100644
--- a/src/genjsbind-parser.y
+++ b/src/genjsbind-parser.y
@@ -38,10 +38,10 @@ int genjsbind_wrap()
%token TOK_IDLFILE
%token TOK_HDR_COMMENT
%token TOK_INTERFACE
+%token TOK_PREAMBLE
%token <text> TOK_STRING_LITERAL
-
-%type <text> Strings
+%token <text> TOK_CCODE_LITERAL
%%
@@ -52,9 +52,14 @@ Statements
;
Statement
- : IdlFile
- | HdrComment
- | Interface
+ :
+ IdlFile
+ |
+ HdrComment
+ |
+ Preamble
+ |
+ Interface
;
/* [3] load a web IDL file */
@@ -70,32 +75,46 @@ IdlFile
HdrComment
: TOK_HDR_COMMENT Strings ';'
{
- genjsbind_header_comment($2);
+
}
;
Strings
- : TOK_STRING_LITERAL
+ :
+ TOK_STRING_LITERAL
{
- $$ = $1;
+ genjsbind_header_comment($1);
}
- | Strings TOK_STRING_LITERAL
+ |
+ 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;
+ genjsbind_header_comment($2);
}
;
Interface
- : TOK_INTERFACE TOK_STRING_LITERAL ';'
+ :
+ TOK_INTERFACE TOK_STRING_LITERAL ';'
+ {
+ genjsbind_interface($2);
+ }
+ ;
+
+Preamble
+ :
+ TOK_PREAMBLE CBlock
+ ;
+
+CBlock
+ :
+ TOK_CCODE_LITERAL
+ {
+ genjsbind_preamble($1);
+ }
+ |
+ CBlock TOK_CCODE_LITERAL
{
- genjsbind_output_interface($2);
+ genjsbind_preamble($2);
}
;
diff --git a/src/genjsbind.c b/src/genjsbind.c
index fcdc944..6bc84b3 100644
--- a/src/genjsbind.c
+++ b/src/genjsbind.c
@@ -6,16 +6,8 @@
#include <getopt.h>
#include <errno.h>
-#include "webidl-ast.h"
-#include "webidl-parser.h"
-#include "genjsbind-parser.h"
#include "jsapi-binding.h"
-#include "genjsbind.h"
-
-extern int genjsbind_debug;
-extern int genjsbind__flex_debug;
-extern void genjsbind_restart(FILE*);
-extern int genjsbind_parse(void);
+#include "options.h"
struct options *options;
@@ -71,7 +63,6 @@ static struct options* process_cmdline(int argc, char **argv)
int main(int argc, char **argv)
{
- FILE *infile;
int res;
options = process_cmdline(argc, argv);
@@ -79,58 +70,25 @@ int main(int argc, char **argv)
return 1; /* bad commandline */
}
- if (options->verbose && (options->outfilename == NULL)) {
- fprintf(stderr, "Error: outputting to stdout with verbose logging would fail\n");
+ if (options->verbose &&
+ (options->outfilename == NULL)) {
+ fprintf(stderr,
+ "Error: output to stdout with verbose logging would fail\n");
return 2;
}
- res = genjsbind_outputopen(options->outfilename);
+ res = genjsbind_parsefile(options->infilename);
if (res != 0) {
+ fprintf(stderr, "Error: parse failed with code %d\n", res);
return res;
}
- /* open input file */
- if ((options->infilename[0] == '-') &&
- (options->infilename[1] == 0)) {
- if (options->verbose) {
- printf("Using stdin for input\n");
- }
- infile = stdin;
- } else {
- if (options->verbose) {
- printf("Opening binding file %s\n", options->infilename);
- }
- infile = fopen(options->infilename, "r");
- }
-
- if (!infile) {
- fprintf(stderr, "Error opening %s: %s\n",
- options->infilename,
- strerror(errno));
- return 3;
- }
-
- if (options->debug) {
- genjsbind_debug = 1;
- genjsbind__flex_debug = 1;
- }
-
- /* set flex to read from file */
- genjsbind_restart(infile);
-
- /* initialise root node */
- webidl_root = webidl_new_node(WEBIDL_NODE_TYPE_ROOT);
-
- /* process binding */
- res = genjsbind_parse();
-
- genjsbind_outputclose();
-
+ res = genjsbind_output(options->outfilename);
if (res != 0) {
- fprintf(stderr, "Error parse failed with code %d\n", res);
+ fprintf(stderr, "Error: output failed with code %d\n", res);
+ unlink(options->outfilename);
return res;
}
-
return 0;
}
diff --git a/src/jsapi-binding.c b/src/jsapi-binding.c
index 51a0df7..9f1bc7e 100644
--- a/src/jsapi-binding.c
+++ b/src/jsapi-binding.c
@@ -5,15 +5,114 @@
#include <string.h>
#include "jsapi-binding.h"
+#include "webidl-ast.h"
+#include "options.h"
-#define HDR_COMMENT_PREABLE "/* Generated by nsgenjsapi\n"
+/* parser and lexer interface */
+extern int genjsbind_debug;
+extern int genjsbind__flex_debug;
+extern void genjsbind_restart(FILE*);
+extern int genjsbind_parse(void);
-static FILE *outfile = NULL;
+
+#define HDR_COMMENT_SEP "\n * "
+#define HDR_COMMENT_SEP_LEN 4
+#define HDR_COMMENT_PREABLE "Generated by nsgenjsapi"HDR_COMMENT_SEP
+
+/* current state */
static char *hdr_comments = NULL;
-static bool hdr_comments_output = false;
+static char *preamble = NULL;
+static char *ifname;
+
+int genjsbind_header_comment(char *comment)
+{
+ char *fullstr;
+ int fulllen;
+ fulllen = strlen(hdr_comments) + strlen(comment) + HDR_COMMENT_SEP_LEN + 1;
+ fullstr = malloc(fulllen);
+ snprintf(fullstr, fulllen, "%s"HDR_COMMENT_SEP"%s", hdr_comments , comment);
+ free(hdr_comments);
+ free(comment);
+ hdr_comments = fullstr;
+
+ return 0;
+}
+
+int genjsbind_preamble(char *ccode)
+{
+ char *fullstr;
+ int fulllen;
+ fulllen = strlen(preamble) + strlen(ccode) + 1;
+ fullstr = malloc(fulllen);
+ snprintf(fullstr, fulllen, "%s%s", preamble , ccode);
+ free(preamble);
+ free(ccode);
+ preamble = fullstr;
+
+ return 0;
+}
+
+int genjsbind_interface(char *interface)
+{
+ ifname = interface;
+ return 0;
+}
+
+static void init_state(void)
+{
+ /* initialise root node */
+ webidl_root = webidl_new_node(WEBIDL_NODE_TYPE_ROOT);
+
+ /* set default comment header text */
+ hdr_comments = strdup(HDR_COMMENT_PREABLE);
+
+ preamble = strdup("");
+}
+
+int genjsbind_parsefile(char *infilename)
+{
+ FILE *infile;
-int genjsbind_outputopen(char *outfilename)
+ /* open input file */
+ if ((infilename[0] == '-') &&
+ (infilename[1] == 0)) {
+ if (options->verbose) {
+ printf("Using stdin for input\n");
+ }
+ infile = stdin;
+ } else {
+ if (options->verbose) {
+ printf("Opening binding file %s\n", options->infilename);
+ }
+ infile = fopen(infilename, "r");
+ }
+
+ if (!infile) {
+ fprintf(stderr, "Error opening %s: %s\n",
+ infilename,
+ strerror(errno));
+ return 3;
+ }
+
+ /* initialise internal state */
+ init_state();
+
+ if (options->debug) {
+ genjsbind_debug = 1;
+ genjsbind__flex_debug = 1;
+ }
+
+ /* set flex to read from file */
+ genjsbind_restart(infile);
+
+ /* process binding */
+ return genjsbind_parse();
+
+}
+
+int genjsbind_output(char *outfilename)
{
+ FILE *outfile = NULL;
/* open output file */
if (outfilename == NULL) {
outfile = stdout;
@@ -28,39 +127,14 @@ int genjsbind_outputopen(char *outfilename)
return 4;
}
- hdr_comments = strdup(HDR_COMMENT_PREABLE);
- return 0;
-}
+ fprintf(outfile, "/* %s\n */\n\n", hdr_comments);
-int genjsbind_outputclose()
-{
- fclose(outfile);
- return 0;
-}
+ fprintf(outfile, "%s", preamble);
-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;
+ fprintf(outfile, "/* interface %s */\n\n", ifname);
- if (hdr_comments_output) {
- fprintf(stderr, "Warning: adding header comments after output already started\n");
- }
- return 0;
-}
+ fclose(outfile);
-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
index ac7929c..33f9776 100644
--- a/src/jsapi-binding.h
+++ b/src/jsapi-binding.h
@@ -1,4 +1,5 @@
-int genjsbind_outputopen(char *outfilename);
-int genjsbind_outputclose(void);
+int genjsbind_parsefile(char *infilename);
+int genjsbind_output(char *outfilename);
int genjsbind_header_comment(char *);
-int genjsbind_output_interface(const char *);
+int genjsbind_interface(char *);
+int genjsbind_preamble(char *ccode);
diff --git a/src/genjsbind.h b/src/options.h
index 47f3c11..47f3c11 100644
--- a/src/genjsbind.h
+++ b/src/options.h
diff --git a/src/webidl-ast.c b/src/webidl-ast.c
index b300383..95b271d 100644
--- a/src/webidl-ast.c
+++ b/src/webidl-ast.c
@@ -5,7 +5,7 @@
#include <errno.h>
#include "webidl-ast.h"
-#include "genjsbind.h"
+#include "options.h"
extern int webidl_debug;
extern int webidl__flex_debug;
diff --git a/test/data/bindings/htmldocument.bnd b/test/data/bindings/htmldocument.bnd
index d370be0..55a8ac7 100644
--- a/test/data/bindings/htmldocument.bnd
+++ b/test/data/bindings/htmldocument.bnd
@@ -10,4 +10,47 @@ hdrcomment "multi"
"line"
"comment";
+hdrcomment "IDL http://www.whatwg.org/specs/web-apps/current-work/#the-document-object";
+
+preamble [[[
+
+#include <dom/dom.h>
+
+#include "utils/config.h"
+#include "utils/log.h"
+
+#include "javascript/jsapi.h"
+
+static JSBool JSAPI_NATIVE(write, JSContext *cx, uintN argc, jsval *vp)
+{
+ JSString* u16_txt;
+ char *txt;
+ unsigned long length;
+ struct jsclass_document_priv *document;
+
+ document = JS_GetInstancePrivate(cx, JS_THIS_OBJECT(cx,vp), &JSCLASS_OBJECT, NULL);
+ if (document == NULL) {
+ return JS_FALSE;
+ }
+
+ if (!JS_ConvertArguments(cx, argc, JSAPI_ARGV(cx, vp), "S", &u16_txt)) {
+ return JS_FALSE;
+ }
+
+ JSString_to_char(u16_txt, txt, length);
+
+ LOG(("content %p parser %p writing %s",
+ document->htmlc, document->htmlc->parser, txt));
+ if (document->htmlc->parser != NULL) {
+ dom_hubbub_parser_insert_chunk(document->htmlc->parser, (uint8_t *)txt, length);
+ }
+ JSAPI_SET_RVAL(cx, vp, JSVAL_VOID);
+
+ foo[23] = bar[n +[x]];
+
+ return JS_TRUE;
+}
+
+]]]
+
interface "Document";