summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorVincent Sanders <vince@kyllikki.org>2019-05-03 17:29:45 +0100
committerVincent Sanders <vince@kyllikki.org>2019-05-03 17:33:28 +0100
commite031876dd52c9d789ec5a3e41156d99962126c2e (patch)
tree99ee5595e59fb033db6265fce2b2670f5fd13595 /src
parent2bfebeabafb9e35290e83103621e5d6a616f5561 (diff)
downloadnsgenbind-e031876dd52c9d789ec5a3e41156d99962126c2e.tar.gz
nsgenbind-e031876dd52c9d789ec5a3e41156d99962126c2e.tar.bz2
Make file output use a common interface
Signed-off-by: Vincent Sanders <vince@kyllikki.org>
Diffstat (limited to 'src')
-rw-r--r--src/Makefile3
-rw-r--r--src/duk-libdom-common.c52
-rw-r--r--src/duk-libdom-dictionary.c101
-rw-r--r--src/duk-libdom-generated.c100
-rw-r--r--src/duk-libdom-interface.c905
-rw-r--r--src/duk-libdom.c148
-rw-r--r--src/duk-libdom.h29
-rw-r--r--src/nsgenbind.c1
-rw-r--r--src/output.c106
-rw-r--r--src/output.h42
10 files changed, 913 insertions, 574 deletions
diff --git a/src/Makefile b/src/Makefile
index a525740..fa1ddc8 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 utils.c webidl-ast.c nsgenbind-ast.c ir.c \
+DIR_SOURCES := nsgenbind.c utils.c output.c \
+ webidl-ast.c nsgenbind-ast.c ir.c \
duk-libdom.c duk-libdom-interface.c duk-libdom-dictionary.c \
duk-libdom-common.c duk-libdom-generated.c
diff --git a/src/duk-libdom-common.c b/src/duk-libdom-common.c
index c76f7a5..0cb1c0d 100644
--- a/src/duk-libdom-common.c
+++ b/src/duk-libdom-common.c
@@ -20,6 +20,7 @@
#include "nsgenbind-ast.h"
#include "webidl-ast.h"
#include "ir.h"
+#include "output.h"
#include "duk-libdom.h"
#define NSGENBIND_PREFACE \
@@ -28,18 +29,18 @@
" * nsgenbind is published under the MIT Licence.\n" \
" * nsgenbind is similar to a compiler is a purely transformative tool which\n" \
" * explicitly makes no copyright claim on this generated output\n" \
- " */"
+ " */\n"
/* exported interface documented in duk-libdom.h */
-int output_tool_preface(FILE* outf)
+int output_tool_preface(struct opctx *outc)
{
- fprintf(outf, "%s\n", NSGENBIND_PREFACE);
+ outputf(outc, "%s", NSGENBIND_PREFACE);
return 0;
}
/* exported interface documented in duk-libdom.h */
-int output_cdata(FILE* outf,
+int output_cdata(struct opctx *outc,
struct genbind_node *node,
enum genbind_node_type nodetype)
{
@@ -51,15 +52,16 @@ int output_cdata(FILE* outf,
genbind_node_getnode(node),
NULL, nodetype));
if (cdata != NULL) {
- fprintf(outf, "%s", cdata);
+ outputf(outc, "%s", cdata);
res = 1;
}
return res;
}
/* exported interface documented in duk-libdom.h */
-int output_ccode(FILE* outf, struct genbind_node *node)
+int output_ccode(struct opctx *outc, struct genbind_node *node)
{
+ int res;
int *line;
char *filename;
@@ -74,27 +76,31 @@ int output_ccode(FILE* outf, struct genbind_node *node)
NULL, GENBIND_NODE_TYPE_FILE));
if ((line != NULL) && (filename != NULL)) {
- fprintf(outf, "/* #line %d \"%s\" */\n", *line, filename);
+ outputf(outc, "#line %d \"%s\"\n", (*line) + 1, filename);
+ res = output_cdata(outc, node, GENBIND_NODE_TYPE_CDATA);
+ output_line(outc);
+ } else {
+ res = output_cdata(outc, node, GENBIND_NODE_TYPE_CDATA);
}
- return output_cdata(outf, node, GENBIND_NODE_TYPE_CDATA);
+ return res;
}
/* exported interface documented in duk-libdom.h */
-int output_tool_prologue(FILE* outf)
+int output_tool_prologue(struct opctx *outc)
{
char *fpath;
fpath = genb_fpath("binding.h");
- fprintf(outf, "\n#include \"%s\"\n", fpath);
+ outputf(outc, "\n#include \"%s\"\n", fpath);
free(fpath);
fpath = genb_fpath("private.h");
- fprintf(outf, "#include \"%s\"\n", fpath);
+ outputf(outc, "#include \"%s\"\n", fpath);
free(fpath);
fpath = genb_fpath("prototype.h");
- fprintf(outf, "#include \"%s\"\n", fpath);
+ outputf(outc, "#include \"%s\"\n", fpath);
free(fpath);
return 0;
@@ -102,7 +108,7 @@ int output_tool_prologue(FILE* outf)
/* exported interface documented in duk-libdom.h */
-int output_ctype(FILE *outf, struct genbind_node *node, bool identifier)
+int output_ctype(struct opctx *outc, struct genbind_node *node, bool identifier)
{
const char *type_cdata = NULL;
struct genbind_node *typename_node;
@@ -113,7 +119,7 @@ int output_ctype(FILE *outf, struct genbind_node *node, bool identifier)
while (typename_node != NULL) {
type_cdata = genbind_node_gettext(typename_node);
- fprintf(outf, "%s", type_cdata);
+ outputf(outc, "%s", type_cdata);
typename_node = genbind_node_find_type(
genbind_node_getnode(node),
@@ -122,25 +128,25 @@ int output_ctype(FILE *outf, struct genbind_node *node, bool identifier)
/* separate all but the last entry with spaces */
if (typename_node != NULL) {
- fputc(' ', outf);
+ outputc(outc, ' ');
}
}
if (identifier) {
- if ((type_cdata != NULL) &&
- (type_cdata[0] != '*') &&
- (type_cdata[0] != ' ')) {
- fputc(' ', outf);
- }
+ if ((type_cdata != NULL) &&
+ (type_cdata[0] != '*') &&
+ (type_cdata[0] != ' ')) {
+ outputc(outc, ' ');
+ }
- output_cdata(outf, node, GENBIND_NODE_TYPE_IDENT);
+ output_cdata(outc, node, GENBIND_NODE_TYPE_IDENT);
}
return 0;
}
/* exported interface documented in duk-libdom.h */
-int output_method_cdata(FILE* outf,
+int output_method_cdata(struct opctx *outc,
struct genbind_node *node,
enum genbind_method_type sel_method_type)
{
@@ -160,7 +166,7 @@ int output_method_cdata(FILE* outf,
GENBIND_NODE_TYPE_METHOD_TYPE));
if ((method_type != NULL) &&
(*method_type == sel_method_type)) {
- output_cdata(outf, method, GENBIND_NODE_TYPE_CDATA);
+ output_cdata(outc, method, GENBIND_NODE_TYPE_CDATA);
}
method = genbind_node_find_type(genbind_node_getnode(node),
diff --git a/src/duk-libdom-dictionary.c b/src/duk-libdom-dictionary.c
index 8c80947..bc53147 100644
--- a/src/duk-libdom-dictionary.c
+++ b/src/duk-libdom-dictionary.c
@@ -20,6 +20,7 @@
#include "nsgenbind-ast.h"
#include "webidl-ast.h"
#include "ir.h"
+#include "output.h"
#include "duk-libdom.h"
/** prefix for all generated functions */
@@ -100,11 +101,12 @@ get_member_default_str(struct ir_entry *dictionarye,
return 0;
}
+
/**
* generate a single class method for an interface operation
*/
static int
-output_member_acessor(FILE* outf,
+output_member_acessor(struct opctx *outc,
struct ir_entry *dictionarye,
struct ir_operation_argument_entry *membere)
{
@@ -148,22 +150,22 @@ output_member_acessor(FILE* outf,
switch (*argument_type) {
case WEBIDL_TYPE_STRING:
- fprintf(outf,
+ outputf(outc,
"const char *\n"
"%s_%s_get_%s(duk_context *ctx, duk_idx_t idx)\n"
"{\n",
DLPFX, dictionarye->class_name, membere->name);
if (defl == NULL) {
- fprintf(outf,
+ outputf(outc,
"\tconst char *ret = NULL; /* No default */\n");
} else {
- fprintf(outf,
+ outputf(outc,
"\tconst char *ret = \"%s\"; /* Default value of %s */\n",
defl, membere->name);
}
- fprintf(outf,
+ outputf(outc,
"\t/* ... obj@idx ... */\n"
"\tduk_get_prop_string(ctx, idx, \"%s\");\n"
"\t/* ... obj@idx ... value/undefined */\n"
@@ -179,22 +181,22 @@ output_member_acessor(FILE* outf,
break;
case WEBIDL_TYPE_BOOL:
- fprintf(outf,
+ outputf(outc,
"duk_bool_t\n"
"%s_%s_get_%s(duk_context *ctx, duk_idx_t idx)\n"
"{\n",
DLPFX, dictionarye->class_name, membere->name);
if (defl == NULL) {
- fprintf(outf,
+ outputf(outc,
"\tduk_bool_t ret = false; /* No default */\n");
} else {
- fprintf(outf,
+ outputf(outc,
"\tduk_bool_t ret = %s; /* Default value of %s */\n",
defl, membere->name);
}
- fprintf(outf,
+ outputf(outc,
"\t/* ... obj@idx ... */\n"
"\tduk_get_prop_string(ctx, idx, \"%s\");\n"
"\t/* ... obj@idx ... value/undefined */\n"
@@ -212,21 +214,22 @@ output_member_acessor(FILE* outf,
case WEBIDL_TYPE_SHORT:
case WEBIDL_TYPE_LONG:
case WEBIDL_TYPE_LONGLONG:
- fprintf(outf,
+ outputf(outc,
"duk_int_t\n"
"%s_%s_get_%s(duk_context *ctx, duk_idx_t idx)\n"
"{\n",
DLPFX, dictionarye->class_name, membere->name);
if (defl == NULL) {
- fprintf(outf, "\tduk_int_t ret = 0; /* No default */\n");
+ outputf(outc,
+ "\tduk_int_t ret = 0; /* No default */\n");
} else {
- fprintf(outf,
+ outputf(outc,
"\tduk_int_t ret = %s; /* Default value of %s */\n",
defl, membere->name);
}
- fprintf(outf,
+ outputf(outc,
"\t/* ... obj@idx ... */\n"
"\tduk_get_prop_string(ctx, idx, \"%s\");\n"
"\t/* ... obj@idx ... value/undefined */\n"
@@ -242,19 +245,19 @@ output_member_acessor(FILE* outf,
case WEBIDL_TYPE_FLOAT:
case WEBIDL_TYPE_DOUBLE:
- fprintf(outf,
+ outputf(outc,
"duk_double_t\n"
"%s_%s_get_%s(duk_context *ctx, duk_idx_t idx)\n",
DLPFX, dictionarye->class_name, membere->name);
- fprintf(outf,
+ outputf(outc,
"{\n"
"\tduk_double_t ret = %s; /* Default value of %s */\n"
"\t/* ... obj@idx ... */\n"
"\tduk_get_prop_string(ctx, idx, \"%s\");\n",
defl, membere->name, membere->name);
- fprintf(outf,
+ outputf(outc,
"\t/* ... obj@idx ... value/undefined */\n"
"\tif (!duk_is_undefined(ctx, -1)) {\n"
"\t\t/* Note, this throws a duk_error if it's not a number */\n"
@@ -271,7 +274,7 @@ output_member_acessor(FILE* outf,
dictionarye->name,
membere->name,
*argument_type);
- fprintf(outf,
+ outputf(outc,
"/* Dictionary %s:%s unhandled type (%d) */\n\n",
dictionarye->name,
membere->name,
@@ -286,7 +289,7 @@ output_member_acessor(FILE* outf,
}
static int
-output_member_acessors(FILE* outf, struct ir_entry *dictionarye)
+output_member_acessors(struct opctx *outc, struct ir_entry *dictionarye)
{
int memberc;
int res = 0;
@@ -295,7 +298,7 @@ output_member_acessors(FILE* outf, struct ir_entry *dictionarye)
memberc < dictionarye->u.dictionary.memberc;
memberc++) {
res = output_member_acessor(
- outf,
+ outc,
dictionarye,
dictionarye->u.dictionary.memberv + memberc);
if (res != 0) {
@@ -310,73 +313,72 @@ output_member_acessors(FILE* outf, struct ir_entry *dictionarye)
/* exported function documented in duk-libdom.h */
int output_dictionary(struct ir *ir, struct ir_entry *dictionarye)
{
- FILE *ifacef;
+ struct opctx *dyop;
int res = 0;
- /* open output file */
- ifacef = genb_fopen_tmp(dictionarye->filename);
- if (ifacef == NULL) {
- return -1;
+ /* open the output */
+ res = output_open(dictionarye->filename, &dyop);
+ if (res != 0) {
+ return res;
}
/* tool preface */
- output_tool_preface(ifacef);
+ output_tool_preface(dyop);
/* binding preface */
- output_method_cdata(ifacef,
+ output_method_cdata(dyop,
ir->binding_node,
GENBIND_METHOD_TYPE_PREFACE);
/* class preface */
- output_method_cdata(ifacef,
+ output_method_cdata(dyop,
dictionarye->class,
GENBIND_METHOD_TYPE_PREFACE);
/* tool prologue */
- output_tool_prologue(ifacef);
+ output_tool_prologue(dyop);
/* binding prologue */
- output_method_cdata(ifacef,
+ output_method_cdata(dyop,
ir->binding_node,
GENBIND_METHOD_TYPE_PROLOGUE);
/* class prologue */
- output_method_cdata(ifacef,
+ output_method_cdata(dyop,
dictionarye->class,
GENBIND_METHOD_TYPE_PROLOGUE);
- fprintf(ifacef, "\n");
+ outputf(dyop, "\n");
-
- res = output_member_acessors(ifacef, dictionarye);
+ res = output_member_acessors(dyop, dictionarye);
if (res != 0) {
goto op_error;
}
- fprintf(ifacef, "\n");
+ outputf(dyop, "\n");
/* class epilogue */
- output_method_cdata(ifacef,
+ output_method_cdata(dyop,
dictionarye->class,
GENBIND_METHOD_TYPE_EPILOGUE);
/* binding epilogue */
- output_method_cdata(ifacef,
+ output_method_cdata(dyop,
ir->binding_node,
GENBIND_METHOD_TYPE_EPILOGUE);
/* class postface */
- output_method_cdata(ifacef,
+ output_method_cdata(dyop,
dictionarye->class,
GENBIND_METHOD_TYPE_POSTFACE);
/* binding postface */
- output_method_cdata(ifacef,
+ output_method_cdata(dyop,
ir->binding_node,
GENBIND_METHOD_TYPE_POSTFACE);
op_error:
- genb_fclose_tmp(ifacef, dictionarye->filename);
+ output_close(dyop);
return res;
}
@@ -385,9 +387,9 @@ op_error:
* generate a single class method declaration for an interface operation
*/
static int
-output_member_declaration(FILE* outf,
- struct ir_entry *dictionarye,
- struct ir_operation_argument_entry *membere)
+output_member_declaration(struct opctx *outc,
+ struct ir_entry *dictionarye,
+ struct ir_operation_argument_entry *membere)
{
struct webidl_node *type_node;
enum webidl_type *argument_type;
@@ -422,13 +424,13 @@ output_member_declaration(FILE* outf,
switch (*argument_type) {
case WEBIDL_TYPE_STRING:
- fprintf(outf,
+ outputf(outc,
"const char *%s_%s_get_%s(duk_context *ctx, duk_idx_t idx);\n",
DLPFX, dictionarye->class_name, membere->name);
break;
case WEBIDL_TYPE_BOOL:
- fprintf(outf,
+ outputf(outc,
"duk_bool_t %s_%s_get_%s(duk_context *ctx, duk_idx_t idx);\n",
DLPFX, dictionarye->class_name, membere->name);
break;
@@ -436,20 +438,20 @@ output_member_declaration(FILE* outf,
case WEBIDL_TYPE_SHORT:
case WEBIDL_TYPE_LONG:
case WEBIDL_TYPE_LONGLONG:
- fprintf(outf,
+ outputf(outc,
"duk_int_t %s_%s_get_%s(duk_context *ctx, duk_idx_t idx);\n",
DLPFX, dictionarye->class_name, membere->name);
break;
case WEBIDL_TYPE_FLOAT:
case WEBIDL_TYPE_DOUBLE:
- fprintf(outf,
+ outputf(outc,
"duk_double_t %s_%s_get_%s(duk_context *ctx, duk_idx_t idx);\n",
DLPFX, dictionarye->class_name, membere->name);
break;
default:
- fprintf(outf,
+ outputf(outc,
"/* Dictionary %s:%s unhandled type (%d) */\n",
dictionarye->name,
membere->name,
@@ -460,7 +462,8 @@ output_member_declaration(FILE* outf,
}
/* exported function documented in duk-libdom.h */
-int output_dictionary_declaration(FILE* outf, struct ir_entry *dictionarye)
+int
+output_dictionary_declaration(struct opctx *outc, struct ir_entry *dictionarye)
{
int memberc;
int res = 0;
@@ -469,7 +472,7 @@ int output_dictionary_declaration(FILE* outf, struct ir_entry *dictionarye)
memberc < dictionarye->u.dictionary.memberc;
memberc++) {
res = output_member_declaration(
- outf,
+ outc,
dictionarye,
dictionarye->u.dictionary.memberv + memberc);
if (res != 0) {
diff --git a/src/duk-libdom-generated.c b/src/duk-libdom-generated.c
index 008f7dc..109b237 100644
--- a/src/duk-libdom-generated.c
+++ b/src/duk-libdom-generated.c
@@ -26,12 +26,13 @@
#include "nsgenbind-ast.h"
#include "webidl-ast.h"
#include "ir.h"
+#include "output.h"
#include "duk-libdom.h"
static int
-output_generated_attribute_user_getter(FILE* outf,
- struct ir_entry *interfacee,
- struct ir_attribute_entry *atributee)
+output_generated_attribute_user_getter(struct opctx *outc,
+ struct ir_entry *interfacee,
+ struct ir_attribute_entry *atributee)
{
UNUSED(interfacee);
@@ -45,7 +46,8 @@ output_generated_attribute_user_getter(FILE* outf,
(atributee->name[1] != 'n')) {
return -1; /* not onxxx */
}
- fprintf(outf,
+
+ outputf(outc,
"\tdom_event_target *et = (dom_event_target *)(((node_private_t *)priv)->node);\n"
"\tdom_string *name;\n"
"\tdom_exception exc;\n\n"
@@ -71,7 +73,7 @@ output_generated_attribute_user_getter(FILE* outf,
/* exported function documented in duk-libdom.h */
int
-output_generated_attribute_getter(FILE* outf,
+output_generated_attribute_getter(struct opctx *outc,
struct ir_entry *interfacee,
struct ir_attribute_entry *atributee)
{
@@ -84,16 +86,16 @@ output_generated_attribute_getter(FILE* outf,
switch (atributee->typev[0].base) {
case WEBIDL_TYPE_STRING:
- fprintf(outf,
+ outputf(outc,
"\tdom_exception exc;\n"
"\tdom_string *str;\n"
"\n");
- fprintf(outf,
+ outputf(outc,
"\texc = dom_%s_get_%s((struct dom_%s *)((node_private_t*)priv)->node, &str);\n",
interfacee->class_name,
atributee->property_name,
interfacee->class_name);
- fprintf(outf,
+ outputf(outc,
"\tif (exc != DOM_NO_ERR) {\n"
"\t\treturn 0;\n"
"\t}\n"
@@ -105,11 +107,13 @@ output_generated_attribute_getter(FILE* outf,
"\t\tdom_string_unref(str);\n"
"\t} else {\n");
if (atributee->typev[0].nullable) {
- fprintf(outf, "\t\tduk_push_null(ctx);\n");
+ outputf(outc,
+ "\t\tduk_push_null(ctx);\n");
} else {
- fprintf(outf, "\t\tduk_push_lstring(ctx, NULL, 0);\n");
+ outputf(outc,
+ "\t\tduk_push_lstring(ctx, NULL, 0);\n");
}
- fprintf(outf,
+ outputf(outc,
"\t}\n"
"\n"
"\treturn 1;\n");
@@ -117,19 +121,21 @@ output_generated_attribute_getter(FILE* outf,
case WEBIDL_TYPE_LONG:
if (atributee->typev[0].modifier == WEBIDL_TYPE_MODIFIER_UNSIGNED) {
- fprintf(outf, "\tdom_ulong l;\n");
+ outputf(outc,
+ "\tdom_ulong l;\n");
} else {
- fprintf(outf, "\tdom_long l;\n");
+ outputf(outc,
+ "\tdom_long l;\n");
}
- fprintf(outf,
+ outputf(outc,
"\tdom_exception exc;\n"
"\n");
- fprintf(outf,
+ outputf(outc,
"\texc = dom_%s_get_%s((struct dom_%s *)((node_private_t*)priv)->node, &l);\n",
interfacee->class_name,
atributee->property_name,
interfacee->class_name);
- fprintf(outf,
+ outputf(outc,
"\tif (exc != DOM_NO_ERR) {\n"
"\t\treturn 0;\n"
"\t}\n"
@@ -141,19 +147,21 @@ output_generated_attribute_getter(FILE* outf,
case WEBIDL_TYPE_SHORT:
if (atributee->typev[0].modifier == WEBIDL_TYPE_MODIFIER_UNSIGNED) {
- fprintf(outf, "\tdom_ushort s;\n");
+ outputf(outc,
+ "\tdom_ushort s;\n");
} else {
- fprintf(outf, "\tdom_short s;\n");
+ outputf(outc,
+ "\tdom_short s;\n");
}
- fprintf(outf,
+ outputf(outc,
"\tdom_exception exc;\n"
"\n");
- fprintf(outf,
+ outputf(outc,
"\texc = dom_%s_get_%s((struct dom_%s *)((node_private_t*)priv)->node, &s);\n",
interfacee->class_name,
atributee->property_name,
interfacee->class_name);
- fprintf(outf,
+ outputf(outc,
"\tif (exc != DOM_NO_ERR) {\n"
"\t\treturn 0;\n"
"\t}\n"
@@ -164,16 +172,16 @@ output_generated_attribute_getter(FILE* outf,
break;
case WEBIDL_TYPE_BOOL:
- fprintf(outf,
+ outputf(outc,
"\tdom_exception exc;\n"
"\tbool b;\n"
"\n");
- fprintf(outf,
+ outputf(outc,
"\texc = dom_%s_get_%s((struct dom_%s *)((node_private_t*)priv)->node, &b);\n",
interfacee->class_name,
atributee->property_name,
interfacee->class_name);
- fprintf(outf,
+ outputf(outc,
"\tif (exc != DOM_NO_ERR) {\n"
"\t\treturn 0;\n"
"\t}\n"
@@ -184,7 +192,7 @@ output_generated_attribute_getter(FILE* outf,
break;
case WEBIDL_TYPE_USER:
- res = output_generated_attribute_user_getter(outf,
+ res = output_generated_attribute_user_getter(outc,
interfacee,
atributee);
break;
@@ -205,7 +213,7 @@ output_generated_attribute_getter(FILE* outf,
}
static int
-output_generated_attribute_user_setter(FILE* outf,
+output_generated_attribute_user_setter(struct opctx *outc,
struct ir_entry *interfacee,
struct ir_attribute_entry *atributee)
{
@@ -222,7 +230,7 @@ output_generated_attribute_user_setter(FILE* outf,
return -1; /* not onxxx */
}
- fprintf(outf,
+ outputf(outc,
"\t/* handlerfn */\n"
"\tduk_push_this(ctx);\n"
"\t/* handlerfn this */\n"
@@ -251,7 +259,7 @@ output_generated_attribute_user_setter(FILE* outf,
/* exported function documented in duk-libdom.h */
int
-output_generated_attribute_setter(FILE* outf,
+output_generated_attribute_setter(struct opctx *outc,
struct ir_entry *interfacee,
struct ir_attribute_entry *atributee)
{
@@ -264,14 +272,14 @@ output_generated_attribute_setter(FILE* outf,
switch (atributee->typev[0].base) {
case WEBIDL_TYPE_STRING:
- fprintf(outf,
+ outputf(outc,
"\tdom_exception exc;\n"
"\tdom_string *str;\n"
"\tduk_size_t slen;\n"
"\tconst char *s;\n");
if ((atributee->treatnullas != NULL) &&
(strcmp(atributee->treatnullas, "EmptyString") == 0)) {
- fprintf(outf,
+ outputf(outc,
"\tif (duk_is_null(ctx, 0)) {\n"
"\t\ts = \"\";\n"
"\t\tslen = 0;\n"
@@ -279,22 +287,22 @@ output_generated_attribute_setter(FILE* outf,
"\t\ts = duk_safe_to_lstring(ctx, 0, &slen);\n"
"\t}\n");
} else {
- fprintf(outf,
+ outputf(outc,
"\ts = duk_safe_to_lstring(ctx, 0, &slen);\n");
}
- fprintf(outf,
+ outputf(outc,
"\n"
"\texc = dom_string_create((const uint8_t *)s, slen, &str);\n"
"\tif (exc != DOM_NO_ERR) {\n"
"\t\treturn 0;\n"
"\t}\n"
"\n");
- fprintf(outf,
+ outputf(outc,
"\texc = dom_%s_set_%s((struct dom_%s *)((node_private_t*)priv)->node, str);\n",
interfacee->class_name,
atributee->property_name,
interfacee->class_name);
- fprintf(outf,
+ outputf(outc,
"\tdom_string_unref(str);\n"
"\tif (exc != DOM_NO_ERR) {\n"
"\t\treturn 0;\n"
@@ -305,26 +313,26 @@ output_generated_attribute_setter(FILE* outf,
case WEBIDL_TYPE_LONG:
if (atributee->typev[0].modifier == WEBIDL_TYPE_MODIFIER_UNSIGNED) {
- fprintf(outf,
+ outputf(outc,
"\tdom_exception exc;\n"
"\tdom_ulong l;\n"
"\n"
"\tl = duk_get_uint(ctx, 0);\n"
"\n");
} else {
- fprintf(outf,
+ outputf(outc,
"\tdom_exception exc;\n"
"\tdom_long l;\n"
"\n"
"\tl = duk_get_int(ctx, 0);\n"
"\n");
}
- fprintf(outf,
+ outputf(outc,
"\texc = dom_%s_set_%s((struct dom_%s *)((node_private_t*)priv)->node, l);\n",
interfacee->class_name,
atributee->property_name,
interfacee->class_name);
- fprintf(outf,
+ outputf(outc,
"\tif (exc != DOM_NO_ERR) {\n"
"\t\treturn 0;\n"
"\t}\n"
@@ -334,26 +342,26 @@ output_generated_attribute_setter(FILE* outf,
case WEBIDL_TYPE_SHORT:
if (atributee->typev[0].modifier == WEBIDL_TYPE_MODIFIER_UNSIGNED) {
- fprintf(outf,
+ outputf(outc,
"\tdom_exception exc;\n"
"\tdom_ushort s;\n"
"\n"
"\ts = duk_get_uint(ctx, 0);\n"
"\n");
} else {
- fprintf(outf,
+ outputf(outc,
"\tdom_exception exc;\n"
"\tdom_short s;\n"
"\n"
"\ts = duk_get_int(ctx, 0);\n"
"\n");
}
- fprintf(outf,
+ outputf(outc,
"\texc = dom_%s_set_%s((struct dom_%s *)((node_private_t*)priv)->node, s);\n",
interfacee->class_name,
atributee->property_name,
interfacee->class_name);
- fprintf(outf,
+ outputf(outc,
"\tif (exc != DOM_NO_ERR) {\n"
"\t\treturn 0;\n"
"\t}\n"
@@ -362,18 +370,18 @@ output_generated_attribute_setter(FILE* outf,
break;
case WEBIDL_TYPE_BOOL:
- fprintf(outf,
+ outputf(outc,
"\tdom_exception exc;\n"
"\tbool b;\n"
"\n"
"\tb = duk_get_boolean(ctx, 0);\n"
"\n");
- fprintf(outf,
+ outputf(outc,
"\texc = dom_%s_set_%s((struct dom_%s *)((node_private_t*)priv)->node, b);\n",
interfacee->class_name,
atributee->property_name,
interfacee->class_name);
- fprintf(outf,
+ outputf(outc,
"\tif (exc != DOM_NO_ERR) {\n"
"\t\treturn 0;\n"
"\t}\n"
@@ -382,7 +390,7 @@ output_generated_attribute_setter(FILE* outf,
break;
case WEBIDL_TYPE_USER:
- res = output_generated_attribute_user_setter(outf,
+ res = output_generated_attribute_user_setter(outc,
interfacee,
atributee);
break;
diff --git a/src/duk-libdom-interface.c b/src/duk-libdom-interface.c
index 0e6697a..f6be419 100644
--- a/src/duk-libdom-interface.c
+++ b/src/duk-libdom-interface.c
@@ -20,6 +20,7 @@
#include "nsgenbind-ast.h"
#include "webidl-ast.h"
#include "ir.h"
+#include "output.h"
#include "duk-libdom.h"
/** prefix for all generated functions */
@@ -27,39 +28,109 @@
#define MAGICPFX "\\xFF\\xFFNETSURF_DUKTAPE_"
+
/**
- * Output code to create a private structure
+ * generate a duktape prototype name
+ */
+static char *get_prototype_name(const char *interface_name)
+{
+ char *proto_name;
+ int pnamelen;
+ int pfxlen;
+
+ /* duplicate the interface name in upper case */
+ pfxlen = SLEN(MAGICPFX) + SLEN("PROTOTYPE_");
+ pnamelen = strlen(interface_name) + 1;
+
+ proto_name = malloc(pnamelen + pfxlen);
+ snprintf(proto_name, pnamelen + pfxlen,
+ "%sPROTOTYPE_%s", MAGICPFX, interface_name);
+ for (pnamelen-- ; pnamelen >= 0; pnamelen--) {
+ proto_name[pnamelen + pfxlen] = toupper(interface_name[pnamelen]);
+ }
+ return proto_name;
+}
+
+
+/**
+ * Compare two nodes to check their c types match.
+ */
+static bool compare_ctypes(struct genbind_node *a, struct genbind_node *b)
+{
+ struct genbind_node *ta;
+ struct genbind_node *tb;
+
+ ta = genbind_node_find_type(genbind_node_getnode(a),
+ NULL, GENBIND_NODE_TYPE_NAME);
+ tb = genbind_node_find_type(genbind_node_getnode(b),
+ NULL, GENBIND_NODE_TYPE_NAME);
+
+ while ((ta != NULL) && (tb != NULL)) {
+ char *txt_a;
+ char *txt_b;
+
+ txt_a = genbind_node_gettext(ta);
+ txt_b = genbind_node_gettext(tb);
+
+ if (strcmp(txt_a, txt_b) != 0) {
+ return false; /* missmatch */
+ }
+
+ ta = genbind_node_find_type(genbind_node_getnode(a),
+ ta, GENBIND_NODE_TYPE_NAME);
+ tb = genbind_node_find_type(genbind_node_getnode(b),
+ tb, GENBIND_NODE_TYPE_NAME);
+ }
+ if (ta != tb) {
+ return false;
+ }
+
+ return true;
+}
+
+
+/**
+ * Generate code to create a private structure
*
+ * \param outc Output context
+ * \param name of class private structure created for.
*/
-static int output_create_private(FILE* outf, char *class_name)
+static int
+output_create_private(struct opctx *outc, char *class_name)
{
- fprintf(outf, "\t/* create private data and attach to instance */\n");
- fprintf(outf, "\t%s_private_t *priv = calloc(1, sizeof(*priv));\n",
+ outputf(outc,
+ "\t/* create private data and attach to instance */\n");
+ outputf(outc,
+ "\t%s_private_t *priv = calloc(1, sizeof(*priv));\n",
class_name);
- fprintf(outf, "\tif (priv == NULL) return 0;\n");
- fprintf(outf, "\tduk_push_pointer(ctx, priv);\n");
- fprintf(outf,
+ outputf(outc,
+ "\tif (priv == NULL) return 0;\n");
+ outputf(outc,
+ "\tduk_push_pointer(ctx, priv);\n");
+ outputf(outc,
"\tduk_put_prop_string(ctx, 0, %s_magic_string_private);\n\n",
DLPFX);
return 0;
}
+
/**
* generate code that gets a private pointer
*/
-static int output_safe_get_private(FILE* outf, char *class_name, int idx)
+static int
+output_safe_get_private(struct opctx *outc, char *class_name, int idx)
{
- fprintf(outf,
+ outputf(outc,
"\t%s_private_t *priv;\n", class_name);
- fprintf(outf,
+ outputf(outc,
"\tduk_get_prop_string(ctx, %d, %s_magic_string_private);\n",
idx, DLPFX);
- fprintf(outf,
+ outputf(outc,
"\tpriv = duk_get_pointer(ctx, -1);\n");
- fprintf(outf,
+ outputf(outc,
"\tduk_pop(ctx);\n");
- fprintf(outf,
+ outputf(outc,
"\tif (priv == NULL) return 0;\n\n");
return 0;
@@ -67,45 +138,23 @@ static int output_safe_get_private(FILE* outf, char *class_name, int idx)
/**
- * generate a duktape prototype name
- */
-static char *get_prototype_name(const char *interface_name)
-{
- char *proto_name;
- int pnamelen;
- int pfxlen;
-
- /* duplicate the interface name in upper case */
- pfxlen = SLEN(MAGICPFX) + SLEN("PROTOTYPE_");
- pnamelen = strlen(interface_name) + 1;
-
- proto_name = malloc(pnamelen + pfxlen);
- snprintf(proto_name, pnamelen + pfxlen, "%sPROTOTYPE_%s", MAGICPFX, interface_name);
- for (pnamelen-- ; pnamelen >= 0; pnamelen--) {
- proto_name[pnamelen + pfxlen] = toupper(interface_name[pnamelen]);
- }
- return proto_name;
-}
-
-
-/**
* generate code that gets a prototype by name
*/
-static int output_get_prototype(FILE* outf, const char *interface_name)
+static int output_get_prototype(struct opctx *outc, const char *interface_name)
{
char *proto_name;
proto_name = get_prototype_name(interface_name);
- fprintf(outf,
+ outputf(outc,
"\t/* get prototype */\n");
- fprintf(outf,
+ outputf(outc,
"\tduk_get_global_string(ctx, %s_magic_string_prototypes);\n",
DLPFX);
- fprintf(outf,
+ outputf(outc,
"\tduk_get_prop_string(ctx, -1, \"%s\");\n",
proto_name);
- fprintf(outf,
+ outputf(outc,
"\tduk_replace(ctx, -2);\n");
free(proto_name);
@@ -116,14 +165,19 @@ static int output_get_prototype(FILE* outf, const char *interface_name)
/**
* generate code that sets a destructor in a prototype
*/
-static int output_set_destructor(FILE* outf, char *class_name, int idx)
+static int output_set_destructor(struct opctx *outc, char *class_name, int idx)
{
- fprintf(outf, "\t/* Set the destructor */\n");
- fprintf(outf, "\tduk_dup(ctx, %d);\n", idx);
- fprintf(outf, "\tduk_push_c_function(ctx, %s_%s___destructor, 1);\n",
+ outputf(outc,
+ "\t/* Set the destructor */\n");
+ outputf(outc,
+ "\tduk_dup(ctx, %d);\n", idx);
+ outputf(outc,
+ "\tduk_push_c_function(ctx, %s_%s___destructor, 1);\n",
DLPFX, class_name);
- fprintf(outf, "\tduk_set_finalizer(ctx, -2);\n");
- fprintf(outf, "\tduk_pop(ctx);\n\n");
+ outputf(outc,
+ "\tduk_set_finalizer(ctx, -2);\n");
+ outputf(outc,
+ "\tduk_pop(ctx);\n\n");
return 0;
}
@@ -132,51 +186,76 @@ static int output_set_destructor(FILE* outf, char *class_name, int idx)
* generate code that sets a constructor in a prototype
*/
static int
-output_set_constructor(FILE* outf, char *class_name, int idx, int argc)
+output_set_constructor(struct opctx *outc, char *class_name, int idx, int argc)
{
- fprintf(outf, "\t/* Set the constructor */\n");
- fprintf(outf, "\tduk_dup(ctx, %d);\n", idx);
- fprintf(outf, "\tduk_push_c_function(ctx, %s_%s___constructor, %d);\n",
+ outputf(outc,
+ "\t/* Set the constructor */\n");
+ outputf(outc,
+ "\tduk_dup(ctx, %d);\n", idx);
+ outputf(outc,
+ "\tduk_push_c_function(ctx, %s_%s___constructor, %d);\n",
DLPFX, class_name, 1 + argc);
- fprintf(outf, "\tduk_put_prop_string(ctx, -2, \"%sINIT\");\n",
+ outputf(outc,
+ "\tduk_put_prop_string(ctx, -2, \"%sINIT\");\n",
MAGICPFX);
- fprintf(outf, "\tduk_pop(ctx);\n\n");
+ outputf(outc,
+ "\tduk_pop(ctx);\n\n");
return 0;
}
+
+/**
+ * generate code to dump javascript stack
+ */
static int
-output_dump_stack(FILE* outf)
+output_dump_stack(struct opctx *outc)
{
if (options->dbglog) {
/* dump stack */
- fprintf(outf, "\tduk_push_context_dump(ctx);\n");
- fprintf(outf, "\tNSLOG(dukky, INFO, \"Stack: %%s\", duk_to_string(ctx, -1));\n");
- fprintf(outf, "\tduk_pop(ctx);\n");
+ outputf(outc,
+ "\tduk_push_context_dump(ctx);\n");
+ outputf(outc,
+ "\tNSLOG(dukky, DEEPDEBUG, \"Stack: %%s\", duk_to_string(ctx, -1));\n");
+ outputf(outc,
+ "\tduk_pop(ctx);\n");
}
return 0;
}
+
/**
* generate code that adds a method in a prototype
*/
static int
-output_add_method(FILE* outf,
+output_add_method(struct opctx *outc,
const char *class_name,
const char *method)
{
- fprintf(outf, "\t/* Add a method */\n");
- fprintf(outf, "\tduk_dup(ctx, 0);\n");
- fprintf(outf, "\tduk_push_string(ctx, \"%s\");\n", method);
- fprintf(outf, "\tduk_push_c_function(ctx, %s_%s_%s, DUK_VARARGS);\n",
+ outputf(outc,
+ "\t/* Add a method */\n");
+ outputf(outc,
+ "\tduk_dup(ctx, 0);\n");
+ outputf(outc,
+ "\tduk_push_string(ctx, \"%s\");\n", method);
+ outputf(outc,
+ "\tduk_push_c_function(ctx, %s_%s_%s, DUK_VARARGS);\n",
DLPFX, class_name, method);
- output_dump_stack(outf);
- fprintf(outf, "\tduk_def_prop(ctx, -3,\n");
- fprintf(outf, "\t DUK_DEFPROP_HAVE_VALUE |\n");
- fprintf(outf, "\t DUK_DEFPROP_HAVE_WRITABLE |\n");
- fprintf(outf, "\t DUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_ENUMERABLE |\n");
- fprintf(outf, "\t DUK_DEFPROP_HAVE_CONFIGURABLE);\n");
- fprintf(outf, "\tduk_pop(ctx);\n\n");
+ output_dump_stack(outc);
+ outputf(outc,
+ "\tduk_def_prop(ctx, -3,\n");
+ outputf(outc,
+ "\t\t DUK_DEFPROP_HAVE_VALUE |\n");
+ outputf(outc,
+ "\t\t DUK_DEFPROP_HAVE_WRITABLE |\n");
+ outputf(outc,
+ "\t\t DUK_DEFPROP_HAVE_ENUMERABLE |\n");
+ outputf(outc,
+ "\t\t DUK_DEFPROP_ENUMERABLE |\n");
+ outputf(outc,
+ "\t\t DUK_DEFPROP_HAVE_CONFIGURABLE);\n");
+ outputf(outc,
+ "\tduk_pop(ctx);\n\n");
return 0;
}
@@ -185,84 +264,133 @@ output_add_method(FILE* outf,
* Generate source to populate a read/write property on a prototype
*/
static int
-output_populate_rw_property(FILE* outf, const char *class_name, const char *property)
+output_populate_rw_property(struct opctx *outc,
+ const char *class_name,
+ const char *property)
{
- fprintf(outf, "\t/* Add read/write property */\n");
- fprintf(outf, "\tduk_dup(ctx, 0);\n");
- fprintf(outf, "\tduk_push_string(ctx, \"%s\");\n", property);
- fprintf(outf, "\tduk_push_c_function(ctx, %s_%s_%s_getter, 0);\n",
+ outputf(outc,
+ "\t/* Add read/write property */\n");
+ outputf(outc,
+ "\tduk_dup(ctx, 0);\n");
+ outputf(outc,
+ "\tduk_push_string(ctx, \"%s\");\n", property);
+ outputf(outc,
+ "\tduk_push_c_function(ctx, %s_%s_%s_getter, 0);\n",
DLPFX, class_name, property);
- fprintf(outf, "\tduk_push_c_function(ctx, %s_%s_%s_setter, 1);\n",
+ outputf(outc,
+ "\tduk_push_c_function(ctx, %s_%s_%s_setter, 1);\n",
DLPFX, class_name, property);
- output_dump_stack(outf);
- fprintf(outf, "\tduk_def_prop(ctx, -4, DUK_DEFPROP_HAVE_GETTER |\n");
- fprintf(outf, "\t\tDUK_DEFPROP_HAVE_SETTER |\n");
- fprintf(outf, "\t\tDUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_ENUMERABLE |\n");
- fprintf(outf, "\t\tDUK_DEFPROP_HAVE_CONFIGURABLE);\n");
- fprintf(outf, "\tduk_pop(ctx);\n\n");
+ output_dump_stack(outc);
+ outputf(outc,
+ "\tduk_def_prop(ctx, -4, DUK_DEFPROP_HAVE_GETTER |\n");
+ outputf(outc,
+ "\t\tDUK_DEFPROP_HAVE_SETTER |\n");
+ outputf(outc,
+ "\t\tDUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_ENUMERABLE |\n");
+ outputf(outc,
+ "\t\tDUK_DEFPROP_HAVE_CONFIGURABLE);\n");
+ outputf(outc,
+ "\tduk_pop(ctx);\n\n");
return 0;
}
+
/**
* Generate source to populate a readonly property on a prototype
*/
static int
-output_populate_ro_property(FILE* outf, const char *class_name, const char *property)
+output_populate_ro_property(struct opctx *outc,
+ const char *class_name,
+ const char *property)
{
- fprintf(outf, "\t/* Add readonly property */\n");
- fprintf(outf, "\tduk_dup(ctx, 0);\n");
- fprintf(outf, "\tduk_push_string(ctx, \"%s\");\n", property);
- fprintf(outf, "\tduk_push_c_function(ctx, %s_%s_%s_getter, 0);\n",
+ outputf(outc,
+ "\t/* Add readonly property */\n");
+ outputf(outc,
+ "\tduk_dup(ctx, 0);\n");
+ outputf(outc,
+ "\tduk_push_string(ctx, \"%s\");\n", property);
+ outputf(outc,
+ "\tduk_push_c_function(ctx, %s_%s_%s_getter, 0);\n",
DLPFX, class_name, property);
- output_dump_stack(outf);
- fprintf(outf, "\tduk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_GETTER |\n");
- fprintf(outf, "\t\tDUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_ENUMERABLE |\n");
- fprintf(outf, "\t\tDUK_DEFPROP_HAVE_CONFIGURABLE);\n");
- fprintf(outf, "\tduk_pop(ctx);\n\n");
+ output_dump_stack(outc);
+ outputf(outc,
+ "\tduk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_GETTER |\n");
+ outputf(outc,
+ "\t\tDUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_ENUMERABLE |\n");
+ outputf(outc,
+ "\t\tDUK_DEFPROP_HAVE_CONFIGURABLE);\n");
+ outputf(outc,
+ "\tduk_pop(ctx);\n\n");
return 0;
}
+
/**
* Generate source to add a constant int value on a prototype
*/
static int
-output_prototype_constant_int(FILE *outf, const char *constant_name, int value)
+output_prototype_constant_int(struct opctx *outc,
+ const char *constant_name,
+ int value)
{
- fprintf(outf, "\tduk_dup(ctx, 0);\n");
- fprintf(outf, "\tduk_push_string(ctx, \"%s\");\n", constant_name);
- fprintf(outf, "\tduk_push_int(ctx, %d);\n", value);
- fprintf(outf, "\tduk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_VALUE |\n");
- fprintf(outf, "\t DUK_DEFPROP_HAVE_WRITABLE | DUK_DEFPROP_HAVE_ENUMERABLE |\n");
- fprintf(outf, "\t DUK_DEFPROP_ENUMERABLE | DUK_DEFPROP_HAVE_CONFIGURABLE);\n");
- fprintf(outf, "\tduk_pop(ctx);\n\n");
+ outputf(outc,
+ "\tduk_dup(ctx, 0);\n");
+ outputf(outc,
+ "\tduk_push_string(ctx, \"%s\");\n", constant_name);
+ outputf(outc,
+ "\tduk_push_int(ctx, %d);\n", value);
+ outputf(outc,
+ "\tduk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_VALUE |\n");
+ outputf(outc,
+ "\t\t DUK_DEFPROP_HAVE_WRITABLE |\n");
+ outputf(outc,
+ "\t\t DUK_DEFPROP_HAVE_ENUMERABLE |\n");
+ outputf(outc,
+ "\t\t DUK_DEFPROP_ENUMERABLE |\n");
+ outputf(outc,
+ "\t\t DUK_DEFPROP_HAVE_CONFIGURABLE);\n");
+ outputf(outc,
+ "\tduk_pop(ctx);\n\n");
return 0;
}
+
/**
* generate code that gets a private pointer for a method
*/
static int
-output_get_method_private(FILE* outf, char *class_name, bool is_global)
+output_get_method_private(struct opctx *outc, char *class_name, bool is_global)
{
- fprintf(outf, "\t/* Get private data for method */\n");
- fprintf(outf, "\t%s_private_t *priv = NULL;\n", class_name);
+ outputf(outc,
+ "\t/* Get private data for method */\n");
+ outputf(outc,
+ "\t%s_private_t *priv = NULL;\n", class_name);
if (is_global) {
- fprintf(outf, "\tduk_push_global_object(ctx);\n");
+ outputf(outc,
+ "\tduk_push_global_object(ctx);\n");
} else {
- fprintf(outf, "\tduk_push_this(ctx);\n");
+ outputf(outc,
+ "\tduk_push_this(ctx);\n");
}
- fprintf(outf, "\tduk_get_prop_string(ctx, -1, %s_magic_string_private);\n",
+ outputf(outc,
+ "\tduk_get_prop_string(ctx, -1, %s_magic_string_private);\n",
DLPFX);
- fprintf(outf, "\tpriv = duk_get_pointer(ctx, -1);\n");
- fprintf(outf, "\tduk_pop_2(ctx);\n");
- fprintf(outf, "\tif (priv == NULL) {\n");
+ outputf(outc,
+ "\tpriv = duk_get_pointer(ctx, -1);\n");
+ outputf(outc,
+ "\tduk_pop_2(ctx);\n");
+ outputf(outc,
+ "\tif (priv == NULL) {\n");
if (options->dbglog) {
- fprintf(outf, "\t\tNSLOG(dukky, INFO, \"priv failed\");\n");
+ outputf(outc,
+ "\t\tNSLOG(dukky, INFO, \"priv failed\");\n");
}
- fprintf(outf, "\t\treturn 0; /* can do? No can do. */\n");
- fprintf(outf, "\t}\n\n");
+ outputf(outc,
+ "\t\treturn 0; /* can do? No can do. */\n");
+ outputf(outc,
+ "\t}\n\n");
return 0;
}
@@ -272,106 +400,81 @@ output_get_method_private(FILE* outf, char *class_name, bool is_global)
* generate the interface constructor
*/
static int
-output_interface_constructor(FILE* outf, struct ir_entry *interfacee)
+output_interface_constructor(struct opctx *outc, struct ir_entry *interfacee)
{
int init_argc;
/* constructor definition */
- fprintf(outf,
+ outputf(outc,
"static duk_ret_t %s_%s___constructor(duk_context *ctx)\n",
DLPFX, interfacee->class_name);
- fprintf(outf,"{\n");
+ outputf(outc,
+ "{\n");
- output_create_private(outf, interfacee->class_name);
+ output_create_private(outc, interfacee->class_name);
/* generate call to initialisor */
- fprintf(outf,
+ outputf(outc,
"\t%s_%s___init(ctx, priv",
DLPFX, interfacee->class_name);
for (init_argc = 1;
init_argc <= interfacee->class_init_argc;
init_argc++) {
- fprintf(outf, ", duk_get_pointer(ctx, %d)", init_argc);
+ outputf(outc,
+ ", duk_get_pointer(ctx, %d)",
+ init_argc);
}
- fprintf(outf, ");\n");
-
-
- fprintf(outf, "\tduk_set_top(ctx, 1);\n");
- fprintf(outf, "\treturn 1;\n");
-
- fprintf(outf, "}\n\n");
+ outputf(outc,
+ ");\n");
+
+ outputf(outc,
+ "\tduk_set_top(ctx, 1);\n");
+ outputf(outc,
+ "\treturn 1;\n");
+ outputf(outc,
+ "}\n\n");
return 0;
}
+
/**
* generate the interface destructor
*/
static int
-output_interface_destructor(FILE* outf, struct ir_entry *interfacee)
+output_interface_destructor(struct opctx *outc, struct ir_entry *interfacee)
{
/* destructor definition */
- fprintf(outf,
+ outputf(outc,
"static duk_ret_t %s_%s___destructor(duk_context *ctx)\n",
DLPFX, interfacee->class_name);
- fprintf(outf,"{\n");
+ outputf(outc,
+ "{\n");
- output_safe_get_private(outf, interfacee->class_name, 0);
+ output_safe_get_private(outc, interfacee->class_name, 0);
/* generate call to finaliser */
- fprintf(outf,
+ outputf(outc,
"\t%s_%s___fini(ctx, priv);\n",
DLPFX, interfacee->class_name);
- fprintf(outf,"\tfree(priv);\n");
- fprintf(outf,"\treturn 0;\n");
+ outputf(outc,
+ "\tfree(priv);\n");
+ outputf(outc,
+ "\treturn 0;\n");
- fprintf(outf, "}\n\n");
+ outputf(outc,
+ "}\n\n");
return 0;
}
-/**
- * Compare two nodes to check their c types match.
- */
-static bool compare_ctypes(struct genbind_node *a, struct genbind_node *b)
-{
- struct genbind_node *ta;
- struct genbind_node *tb;
-
- ta = genbind_node_find_type(genbind_node_getnode(a),
- NULL, GENBIND_NODE_TYPE_NAME);
- tb = genbind_node_find_type(genbind_node_getnode(b),
- NULL, GENBIND_NODE_TYPE_NAME);
-
- while ((ta != NULL) && (tb != NULL)) {
- char *txt_a;
- char *txt_b;
-
- txt_a = genbind_node_gettext(ta);
- txt_b = genbind_node_gettext(tb);
-
- if (strcmp(txt_a, txt_b) != 0) {
- return false; /* missmatch */
- }
-
- ta = genbind_node_find_type(genbind_node_getnode(a),
- ta, GENBIND_NODE_TYPE_NAME);
- tb = genbind_node_find_type(genbind_node_getnode(b),
- tb, GENBIND_NODE_TYPE_NAME);
- }
- if (ta != tb) {
- return false;
- }
-
- return true;
-}
/**
* generate an initialisor call to parent interface
*/
static int
-output_interface_inherit_init(FILE* outf,
+output_interface_inherit_init(struct opctx *outc,
struct ir_entry *interfacee,
struct ir_entry *inherite)
{
@@ -396,8 +499,8 @@ output_interface_inherit_init(FILE* outf,
GENBIND_METHOD_TYPE_INIT);
-
- fprintf(outf, "\t%s_%s___init(ctx, &priv->parent",
+ outputf(outc,
+ "\t%s_%s___init(ctx, &priv->parent",
DLPFX, inherite->class_name);
/* for each parameter in the parent find a matching named
@@ -421,7 +524,8 @@ output_interface_inherit_init(FILE* outf,
GENBIND_NODE_TYPE_PARAMETER,
param_name);
if (param_node == NULL) {
- fprintf(stderr, "class \"%s\" (interface %s) parent class \"%s\" (interface %s) initialisor requires a parameter \"%s\" with compatible identifier\n",
+ fprintf(stderr,
+ "class \"%s\" (interface %s) parent class \"%s\" (interface %s) initialisor requires a parameter \"%s\" with compatible identifier\n",
interfacee->class_name,
interfacee->name,
inherite->class_name,
@@ -429,18 +533,18 @@ output_interface_inherit_init(FILE* outf,
param_name);
return -1;
} else {
- fprintf(outf, ", ");
+ outputf(outc, ", ");
/* cast the parameter if required */
if (compare_ctypes(param_node,
inh_param_node) == false) {
- fputc('(', outf);
- output_ctype(outf, inh_param_node, false);
- fputc(')', outf);
+ outputc(outc, '(');
+ output_ctype(outc, inh_param_node, false);
+ outputc(outc, ')');
}
/* output the parameter identifier */
- output_cdata(outf, param_node, GENBIND_NODE_TYPE_IDENT);
+ output_cdata(outc, param_node, GENBIND_NODE_TYPE_IDENT);
}
inh_param_node = genbind_node_find_type(
@@ -448,22 +552,24 @@ output_interface_inherit_init(FILE* outf,
inh_param_node, GENBIND_NODE_TYPE_METHOD);
}
- fprintf(outf, ");\n");
+ outputf(outc, ");\n");
return 0;
}
+
static int
-output_interface_init_declaration(FILE* outf,
+output_interface_init_declaration(struct opctx *outc,
struct ir_entry *interfacee,
struct genbind_node *init_node)
{
struct genbind_node *param_node;
if (interfacee->refcount == 0) {
- fprintf(outf, "static ");
+ outputf(outc, "static ");
}
- fprintf(outf,
+
+ outputf(outc,
"void %s_%s___init(duk_context *ctx, %s_private_t *priv",
DLPFX, interfacee->class_name, interfacee->class_name);
@@ -476,22 +582,26 @@ output_interface_init_declaration(FILE* outf,
NULL, GENBIND_NODE_TYPE_PARAMETER);
while (param_node != NULL) {
interfacee->class_init_argc++;
- fprintf(outf, ", ");
+ outputf(outc, ", ");
- output_ctype(outf, param_node, true);
+ output_ctype(outc, param_node, true);
param_node = genbind_node_find_type(
genbind_node_getnode(init_node),
param_node, GENBIND_NODE_TYPE_PARAMETER);
}
- fprintf(outf,")");
+ outputc(outc, ')');
return 0;
}
+
+/**
+ * generate code for interface (class) initialisor
+ */
static int
-output_interface_init(FILE* outf,
+output_interface_init(struct opctx *outc,
struct ir_entry *interfacee,
struct ir_entry *inherite)
{
@@ -504,33 +614,37 @@ output_interface_init(FILE* outf,
GENBIND_METHOD_TYPE_INIT);
/* initialisor definition */
- output_interface_init_declaration(outf, interfacee, init_node);
+ output_interface_init_declaration(outc, interfacee, init_node);
- fprintf(outf,"\n{\n");
+ outputf(outc, "\n{\n");
/* if this interface inherits ensure we call its initialisor */
- res = output_interface_inherit_init(outf, interfacee, inherite);
+ res = output_interface_inherit_init(outc, interfacee, inherite);
if (res != 0) {
return res;
}
/* generate log statement */
if (options->dbglog) {
- fprintf(outf,
+ outputf(outc,
"\tNSLOG(dukky, INFO, \"Initialise %%p (priv=%%p)\", duk_get_heapptr(ctx, 0), priv);\n" );
}
/* output the initaliser code from the binding */
- output_ccode(outf, init_node);
+ output_ccode(outc, init_node);
- fprintf(outf, "}\n\n");
+ outputf(outc, "}\n\n");
return 0;
}
+
+/**
+ * generate code for interface (class) finaliser
+ */
static int
-output_interface_fini(FILE* outf,
+output_interface_fini(struct opctx *outc,
struct ir_entry *interfacee,
struct ir_entry *inherite)
{
@@ -541,32 +655,31 @@ output_interface_fini(FILE* outf,
NULL,
GENBIND_METHOD_TYPE_FINI);
-
/* finaliser definition */
if (interfacee->refcount == 0) {
- fprintf(outf, "static ");
+ outputf(outc, "static ");
}
- fprintf(outf,
+ outputf(outc,
"void %s_%s___fini(duk_context *ctx, %s_private_t *priv)\n",
DLPFX, interfacee->class_name, interfacee->class_name);
- fprintf(outf,"{\n");
+ outputf(outc, "{\n");
/* generate log statement */
if (options->dbglog) {
- fprintf(outf,
+ outputf(outc,
"\tNSLOG(dukky, INFO, \"Finalise %%p\", duk_get_heapptr(ctx, 0));\n" );
}
/* output the finialisor code from the binding */
- output_cdata(outf, fini_node, GENBIND_NODE_TYPE_CDATA);
+ output_cdata(outc, fini_node, GENBIND_NODE_TYPE_CDATA);
/* if this interface inherits ensure we call its finaliser */
if (inherite != NULL) {
- fprintf(outf,
+ outputf(outc,
"\t%s_%s___fini(ctx, &priv->parent);\n",
DLPFX, inherite->class_name);
}
- fprintf(outf, "}\n\n");
+ outputf(outc, "}\n\n");
return 0;
}
@@ -576,37 +689,38 @@ output_interface_fini(FILE* outf,
* generate a prototype add for a single class method
*/
static int
-output_prototype_method(FILE* outf,
+output_prototype_method(struct opctx *outc,
struct ir_entry *interfacee,
struct ir_operation_entry *operatione)
{
if (operatione->name != NULL) {
/* normal method on prototype */
- output_add_method(outf,
+ output_add_method(outc,
interfacee->class_name,
operatione->name);
} else {
/* special method on prototype */
- fprintf(outf,
+ outputf(outc,
"\t/* Special method on prototype - UNIMPLEMENTED */\n\n");
}
return 0;
}
+
/**
* generate prototype method definitions
*/
static int
-output_prototype_methods(FILE *outf, struct ir_entry *entry)
+output_prototype_methods(struct opctx *outc, struct ir_entry *entry)
{
int opc;
int res = 0;
for (opc = 0; opc < entry->u.interface.operationc; opc++) {
res = output_prototype_method(
- outf,
+ outc,
entry,
entry->u.interface.operationv + opc);
if (res != 0) {
@@ -619,33 +733,34 @@ output_prototype_methods(FILE *outf, struct ir_entry *entry)
static int
-output_prototype_attribute(FILE *outf,
+output_prototype_attribute(struct opctx *outc,
struct ir_entry *interfacee,
struct ir_attribute_entry *attributee)
{
if ((attributee->putforwards == NULL) &&
(attributee->modifier == WEBIDL_TYPE_MODIFIER_READONLY)) {
- return output_populate_ro_property(outf,
+ return output_populate_ro_property(outc,
interfacee->class_name,
attributee->name);
}
- return output_populate_rw_property(outf,
+ return output_populate_rw_property(outc,
interfacee->class_name,
attributee->name);
}
+
/**
* generate prototype attribute definitions
*/
static int
-output_prototype_attributes(FILE *outf, struct ir_entry *entry)
+output_prototype_attributes(struct opctx *outc, struct ir_entry *entry)
{
int attrc;
int res = 0;
for (attrc = 0; attrc < entry->u.interface.attributec; attrc++) {
res = output_prototype_attribute(
- outf,
+ outc,
entry,
entry->u.interface.attributev + attrc);
if (res != 0) {
@@ -656,6 +771,7 @@ output_prototype_attributes(FILE *outf, struct ir_entry *entry)
return res;
}
+
/**
* output constants on the prototype
*
@@ -663,7 +779,7 @@ output_prototype_attributes(FILE *outf, struct ir_entry *entry)
* check the type node base value.
*/
static int
-output_prototype_constant(FILE *outf,
+output_prototype_constant(struct opctx *outc,
struct ir_constant_entry *constante)
{
int *value;
@@ -674,23 +790,24 @@ output_prototype_constant(FILE *outf,
NULL,
WEBIDL_NODE_TYPE_LITERAL_INT));
- output_prototype_constant_int(outf, constante->name, *value);
+ output_prototype_constant_int(outc, constante->name, *value);
return 0;
}
+
/**
* generate prototype constant definitions
*/
static int
-output_prototype_constants(FILE *outf, struct ir_entry *entry)
+output_prototype_constants(struct opctx *outc, struct ir_entry *entry)
{
int attrc;
int res = 0;
for (attrc = 0; attrc < entry->u.interface.constantc; attrc++) {
res = output_prototype_constant(
- outf,
+ outc,
entry->u.interface.constantv + attrc);
if (res != 0) {
break;
@@ -700,14 +817,16 @@ output_prototype_constants(FILE *outf, struct ir_entry *entry)
return res;
}
+
static int
-output_global_create_prototype(FILE* outf,
+output_global_create_prototype(struct opctx *outc,
struct ir *ir,
struct ir_entry *interfacee)
{
int idx;
- fprintf(outf, "\t/* Create interface objects */\n");
+ outputf(outc,
+ "\t/* Create interface objects */\n");
for (idx = 0; idx < ir->entryc; idx++) {
struct ir_entry *entry;
@@ -720,12 +839,13 @@ output_global_create_prototype(FILE* outf,
}
if (entry == interfacee) {
- fprintf(outf, "\tduk_dup(ctx, 0);\n");
+ outputf(outc,
+ "\tduk_dup(ctx, 0);\n");
} else {
- output_get_prototype(outf, entry->name);
+ output_get_prototype(outc, entry->name);
}
- fprintf(outf,
+ outputf(outc,
"\tdukky_inject_not_ctr(ctx, 0, \"%s\");\n",
entry->name);
}
@@ -738,7 +858,7 @@ output_global_create_prototype(FILE* outf,
* generate the interface prototype creator
*/
static int
-output_interface_prototype(FILE* outf,
+output_interface_prototype(struct opctx *outc,
struct ir *ir,
struct ir_entry *interfacee,
struct ir_entry *inherite)
@@ -747,74 +867,81 @@ output_interface_prototype(FILE* outf,
/* find the prototype method on the class */
proto_node = genbind_node_find_method(interfacee->class,
- NULL,
- GENBIND_METHOD_TYPE_PROTOTYPE);
+ NULL,
+ GENBIND_METHOD_TYPE_PROTOTYPE);
/* prototype definition */
- fprintf(outf, "duk_ret_t %s_%s___proto(duk_context *ctx, void *udata)\n",
+ outputf(outc,
+ "duk_ret_t %s_%s___proto(duk_context *ctx, void *udata)\n",
DLPFX, interfacee->class_name);
- fprintf(outf,"{\n");
+ outputf(outc, "{\n");
/* Output any binding data first */
- if (output_cdata(outf, proto_node, GENBIND_NODE_TYPE_CDATA) != 0) {
- fprintf(outf,"\n");
+ if (output_cdata(outc, proto_node, GENBIND_NODE_TYPE_CDATA) != 0) {
+ outputf(outc,
+ "\n");
}
/* generate prototype chaining if interface has a parent */
if (inherite != NULL) {
- fprintf(outf,
+ outputf(outc,
"\t/* Set this prototype's prototype (left-parent) */\n");
- output_get_prototype(outf, inherite->name);
- fprintf(outf, "\tduk_set_prototype(ctx, 0);\n\n");
+ output_get_prototype(outc, inherite->name);
+ outputf(outc,
+ "\tduk_set_prototype(ctx, 0);\n\n");
}
/* generate setting of methods */
- output_prototype_methods(outf, interfacee);
+ output_prototype_methods(outc, interfacee);
/* generate setting of attributes */
- output_prototype_attributes(outf, interfacee);
+ output_prototype_attributes(outc, interfacee);
/* generate setting of constants */
- output_prototype_constants(outf, interfacee);
+ output_prototype_constants(outc, interfacee);
/* if this is the global object, output all interfaces which do not
* prevent us from doing so
*/
if (interfacee->u.interface.primary_global) {
- output_global_create_prototype(outf, ir, interfacee);
+ output_global_create_prototype(outc, ir, interfacee);
}
/* generate setting of destructor */
- output_set_destructor(outf, interfacee->class_name, 0);
+ output_set_destructor(outc, interfacee->class_name, 0);
/* generate setting of constructor */
- output_set_constructor(outf,
+ output_set_constructor(outc,
interfacee->class_name,
0,
interfacee->class_init_argc);
- fprintf(outf,"\treturn 1; /* The prototype object */\n");
+ outputf(outc,
+ "\treturn 1; /* The prototype object */\n");
- fprintf(outf, "}\n\n");
+ outputf(outc,
+ "}\n\n");
return 0;
}
+
/**
* generate a single class method for an interface operation with elipsis
*/
static int
-output_interface_elipsis_operation(FILE* outf,
- struct ir_entry *interfacee,
- struct ir_operation_entry *operatione)
+output_interface_elipsis_operation(struct opctx *outc,
+ struct ir_entry *interfacee,
+ struct ir_operation_entry *operatione)
{
int cdatac; /* cdata blocks output */
/* overloaded method definition */
- fprintf(outf,
+ outputf(outc,
"static duk_ret_t %s_%s_%s(duk_context *ctx)\n",
DLPFX, interfacee->class_name, operatione->name);
- fprintf(outf,"{\n");
+ outputf(outc,
+ "{\n");
/**
* \todo This is where the checking of the parameters to the
@@ -824,47 +951,51 @@ output_interface_elipsis_operation(FILE* outf,
"Elipsis parameters not checked: method %s::%s();",
interfacee->name, operatione->name);
- output_get_method_private(outf, interfacee->class_name,
+ output_get_method_private(outc, interfacee->class_name,
interfacee->u.interface.primary_global);
- cdatac = output_ccode(outf, operatione->method);
+ cdatac = output_ccode(outc, operatione->method);
if (cdatac == 0) {
/* no implementation so generate default */
WARN(WARNING_UNIMPLEMENTED,
"Unimplemented: method %s::%s();",
interfacee->name, operatione->name);
- fprintf(outf,"\treturn 0;\n");
+ outputf(outc,
+ "\treturn 0;\n");
}
- fprintf(outf, "}\n\n");
+ outputf(outc,
+ "}\n\n");
return 0;
}
+
/**
* generate a single class method for an interface overloaded operation
*/
static int
-output_interface_overloaded_operation(FILE* outf,
- struct ir_entry *interfacee,
- struct ir_operation_entry *operatione)
+output_interface_overloaded_operation(struct opctx *outc,
+ struct ir_entry *interfacee,
+ struct ir_operation_entry *operatione)
{
int cdatac; /* cdata blocks output */
/* overloaded method definition */
- fprintf(outf,
+ outputf(outc,
"static duk_ret_t %s_%s_%s(duk_context *ctx)\n",
DLPFX, interfacee->class_name, operatione->name);
- fprintf(outf,"{\n");
+ outputf(outc,
+ "{\n");
/** \todo This is where the checking of the parameters to the
* overloaded operation should go
*/
- output_get_method_private(outf, interfacee->class_name,
+ output_get_method_private(outc, interfacee->class_name,
interfacee->u.interface.primary_global);
- cdatac = output_cdata(outf,
+ cdatac = output_cdata(outc,
operatione->method,
GENBIND_NODE_TYPE_CDATA);
@@ -873,24 +1004,28 @@ output_interface_overloaded_operation(FILE* outf,
WARN(WARNING_UNIMPLEMENTED,
"Unimplemented: method %s::%s();",
interfacee->name, operatione->name);
- fprintf(outf,"\treturn 0;\n");
+ outputf(outc,
+ "\treturn 0;\n");
}
- fprintf(outf, "}\n\n");
+ outputf(outc,
+ "}\n\n");
return 0;
}
+
/**
* generate a single class method for an interface special operation
*/
static int
-output_interface_special_operation(FILE* outf,
- struct ir_entry *interfacee,
- struct ir_operation_entry *operatione)
+output_interface_special_operation(struct opctx *outc,
+ struct ir_entry *interfacee,
+ struct ir_operation_entry *operatione)
{
/* special method definition */
- fprintf(outf, "/* Special method definition - UNIMPLEMENTED */\n\n");
+ outputf(outc,
+ "/* Special method definition - UNIMPLEMENTED */\n\n");
WARN(WARNING_UNIMPLEMENTED,
"Special operation on interface %s (operation entry %p)",
@@ -900,11 +1035,13 @@ output_interface_special_operation(FILE* outf,
return 0;
}
+
/**
* generate default values on the duk stack
*/
static int
-output_operation_optional_defaults(FILE* outf,
+output_operation_optional_defaults(
+ struct opctx *outc,
struct ir_operation_argument_entry *argumentv,
int argumentc)
{
@@ -930,47 +1067,49 @@ output_operation_optional_defaults(FILE* outf,
switch (lit_type) {
case WEBIDL_NODE_TYPE_LITERAL_NULL:
- fprintf(outf,
+ outputf(outc,
"\t\tduk_push_null(ctx);\n");
break;
case WEBIDL_NODE_TYPE_LITERAL_INT:
lit_int = webidl_node_getint(lit_node);
- fprintf(outf,
+ outputf(outc,
"\t\tduk_push_int(ctx, %d);\n",
*lit_int);
break;
case WEBIDL_NODE_TYPE_LITERAL_BOOL:
lit_int = webidl_node_getint(lit_node);
- fprintf(outf,
+ outputf(outc,
"\t\tduk_push_boolean(ctx, %d);\n",
*lit_int);
break;
case WEBIDL_NODE_TYPE_LITERAL_STRING:
lit_str = webidl_node_gettext(lit_node);
- fprintf(outf,
+ outputf(outc,
"\t\tduk_push_string(ctx, \"%s\");\n",
lit_str);
break;
case WEBIDL_NODE_TYPE_LITERAL_FLOAT:
default:
- fprintf(outf,
+ outputf(outc,
"\t\tduk_push_undefined(ctx);\n");
break;
}
} else {
- fprintf(outf, "\t\tduk_push_undefined(ctx);\n");
+ outputf(outc,
+ "\t\tduk_push_undefined(ctx);\n");
}
}
return 0;
}
+
static int
output_operation_argument_type_check(
- FILE* outf,
+ struct opctx *outc,
struct ir_entry *interfacee,
struct ir_operation_entry *operatione,
struct ir_operation_overload_entry *overloade,
@@ -1017,19 +1156,20 @@ output_operation_argument_type_check(
return 0;
}
- fprintf(outf, "\tif (%s_argc > %d) {\n", DLPFX, argidx);
+ outputf(outc,
+ "\tif (%s_argc > %d) {\n", DLPFX, argidx);
switch (*argument_type) {
case WEBIDL_TYPE_STRING:
/* coerce values to string */
- fprintf(outf,
+ outputf(outc,
"\t\tif (!duk_is_string(ctx, %d)) {\n"
"\t\t\tduk_to_string(ctx, %d);\n"
"\t\t}\n", argidx, argidx);
break;
case WEBIDL_TYPE_BOOL:
- fprintf(outf,
+ outputf(outc,
"\t\tif (!duk_is_boolean(ctx, %d)) {\n"
"\t\t\treturn duk_error(ctx, DUK_ERR_ERROR, %s_error_fmt_bool_type, %d, \"%s\");\n"
"\t\t}\n", argidx, DLPFX, argidx, argumente->name);
@@ -1040,19 +1180,21 @@ output_operation_argument_type_check(
case WEBIDL_TYPE_SHORT:
case WEBIDL_TYPE_LONG:
case WEBIDL_TYPE_LONGLONG:
- fprintf(outf,
+ outputf(outc,
"\t\tif (!duk_is_number(ctx, %d)) {\n"
"\t\t\treturn duk_error(ctx, DUK_ERR_ERROR, %s_error_fmt_number_type, %d, \"%s\");\n"
- "\t\t}\n", argidx, DLPFX, argidx, argumente->name);
+ "\t\t}\n",
+ argidx, DLPFX, argidx, argumente->name);
break;
default:
- fprintf(outf,
+ outputf(outc,
"\t\t/* unhandled type check */\n");
}
- fprintf(outf, "\t}\n");
+ outputf(outc,
+ "\t}\n");
return 0;
}
@@ -1062,7 +1204,7 @@ output_operation_argument_type_check(
* generate a single class method for an interface operation
*/
static int
-output_interface_operation(FILE* outf,
+output_interface_operation(struct opctx *outc,
struct ir_entry *interfacee,
struct ir_operation_entry *operatione)
{
@@ -1073,19 +1215,19 @@ output_interface_operation(FILE* outf,
int optargc; /* loop counter for optional arguments */
if (operatione->name == NULL) {
- return output_interface_special_operation(outf,
+ return output_interface_special_operation(outc,
interfacee,
operatione);
}
if (operatione->overloadc != 1) {
- return output_interface_overloaded_operation(outf,
+ return output_interface_overloaded_operation(outc,
interfacee,
operatione);
}
if (operatione->overloadv->elipsisc != 0) {
- return output_interface_elipsis_operation(outf,
+ return output_interface_elipsis_operation(outc,
interfacee,
operatione);
}
@@ -1093,10 +1235,11 @@ output_interface_operation(FILE* outf,
/* normal method definition */
overloade = operatione->overloadv;
- fprintf(outf,
+ outputf(outc,
"static duk_ret_t %s_%s_%s(duk_context *ctx)\n",
DLPFX, interfacee->class_name, operatione->name);
- fprintf(outf,"{\n");
+ outputf(outc,
+ "{\n");
/* check arguments */
@@ -1104,40 +1247,40 @@ output_interface_operation(FILE* outf,
fixedargc = overloade->argumentc - overloade->optionalc;
- fprintf(outf,
+ outputf(outc,
"\t/* ensure the parameters are present */\n"
"\tduk_idx_t %s_argc = duk_get_top(ctx);\n\t", DLPFX);
if (fixedargc > 0) {
- fprintf(outf,
- "if (%s_argc < %d) {\n"
- "\t\t/* not enough arguments */\n"
- "\t\treturn duk_error(ctx, DUK_RET_TYPE_ERROR, %s_error_fmt_argument, %d, %s_argc);\n"
- "\t} else ",
- DLPFX,
- fixedargc,
- DLPFX,
- fixedargc,
- DLPFX);
+ outputf(outc,
+ "if (%s_argc < %d) {\n",
+ DLPFX, fixedargc);
+ outputf(outc,
+ "\t\t/* not enough arguments */\n");
+ outputf(outc,
+ "\t\treturn duk_error(ctx, DUK_RET_TYPE_ERROR, %s_error_fmt_argument, %d, %s_argc);\n",
+ DLPFX, fixedargc, DLPFX);
+ outputf(outc,
+ "\t} else ");
}
for (optargc = fixedargc;
optargc < overloade->argumentc;
optargc++) {
- fprintf(outf,
+ outputf(outc,
"if (%s_argc == %d) {\n"
"\t\t/* %d optional arguments need adding */\n",
DLPFX,
optargc,
overloade->argumentc - optargc);
- output_operation_optional_defaults(outf,
+ output_operation_optional_defaults(outc,
overloade->argumentv + optargc,
overloade->argumentc - optargc);
- fprintf(outf,
+ outputf(outc,
"\t} else ");
}
- fprintf(outf,
+ outputf(outc,
"if (%s_argc > %d) {\n"
"\t\t/* remove extraneous parameters */\n"
"\t\tduk_set_top(ctx, %d);\n"
@@ -1145,24 +1288,26 @@ output_interface_operation(FILE* outf,
DLPFX,
overloade->argumentc,
overloade->argumentc);
- fprintf(outf, "\n");
+ outputf(outc,
+ "\n");
/* generate argument type checks */
- fprintf(outf, "\t/* check types of passed arguments are correct */\n");
+ outputf(outc,
+ "\t/* check types of passed arguments are correct */\n");
for (argidx = 0; argidx < overloade->argumentc; argidx++) {
- output_operation_argument_type_check(outf,
+ output_operation_argument_type_check(outc,
interfacee,
operatione,
overloade,
argidx);
}
- output_get_method_private(outf, interfacee->class_name,
+ output_get_method_private(outc, interfacee->class_name,
interfacee->u.interface.primary_global);
- cdatac = output_ccode(outf, operatione->method);
+ cdatac = output_ccode(outc, operatione->method);
if (cdatac == 0) {
/* no implementation so generate default */
WARN(WARNING_UNIMPLEMENTED,
@@ -1170,13 +1315,16 @@ output_interface_operation(FILE* outf,
interfacee->name, operatione->name);
if (options->dbglog) {
- fprintf(outf, "\tNSLOG(dukky, WARNING, \"Unimplemented\");\n" );
+ outputf(outc,
+ "\tNSLOG(dukky, WARNING, \"Unimplemented\");\n");
}
- fprintf(outf,"\treturn 0;\n");
+ outputf(outc,
+ "\treturn 0;\n");
}
- fprintf(outf, "}\n\n");
+ outputf(outc,
+ "}\n\n");
return 0;
}
@@ -1185,14 +1333,14 @@ output_interface_operation(FILE* outf,
* generate class methods for each interface operation
*/
static int
-output_interface_operations(FILE* outf, struct ir_entry *ife)
+output_interface_operations(struct opctx *outc, struct ir_entry *ife)
{
int opc;
int res = 0;
for (opc = 0; opc < ife->u.interface.operationc; opc++) {
res = output_interface_operation(
- outf,
+ outc,
ife,
ife->u.interface.operationv + opc);
if (res != 0) {
@@ -1209,31 +1357,34 @@ output_interface_operations(FILE* outf, struct ir_entry *ife)
* Output class property getter for a single attribute
*/
static int
-output_attribute_getter(FILE* outf,
+output_attribute_getter(struct opctx *outc,
struct ir_entry *interfacee,
struct ir_attribute_entry *atributee)
{
/* getter definition */
- fprintf(outf,
+ outputf(outc,
"static duk_ret_t %s_%s_%s_getter(duk_context *ctx)\n",
DLPFX, interfacee->class_name, atributee->name);
- fprintf(outf,"{\n");
+ outputf(outc,
+ "{\n");
- output_get_method_private(outf, interfacee->class_name,
+ output_get_method_private(outc,
+ interfacee->class_name,
interfacee->u.interface.primary_global);
/* if binding available for this attribute getter process it */
if (atributee->getter != NULL) {
int res;
- res = output_ccode(outf, atributee->getter);
+ res = output_ccode(outc, atributee->getter);
if (res == 0) {
/* no code provided for this getter so generate */
- res = output_generated_attribute_getter(outf,
+ res = output_generated_attribute_getter(outc,
interfacee,
atributee);
}
if (res >= 0) {
- fprintf(outf, "}\n\n");
+ outputf(outc,
+ "}\n\n");
return res;
}
}
@@ -1256,10 +1407,11 @@ output_attribute_getter(FILE* outf,
type_str);
if (options->dbglog) {
- fprintf(outf, "\tNSLOG(dukky, WARNING, \"Unimplemented\");\n" );
+ outputf(outc,
+ "\tNSLOG(dukky, WARNING, \"Unimplemented\");\n" );
}
- fprintf(outf,
+ outputf(outc,
"\treturn 0;\n"
"}\n\n");
@@ -1271,19 +1423,20 @@ output_attribute_getter(FILE* outf,
* Generate class property setter for a putforwards attribute
*/
static int
-output_putforwards_setter(FILE* outf,
- struct ir_entry *interfacee,
- struct ir_attribute_entry *atributee)
+output_putforwards_setter(struct opctx *outc,
+ struct ir_entry *interfacee,
+ struct ir_attribute_entry *atributee)
{
/* generate autogenerated putforwards */
- fprintf(outf,"\tduk_ret_t get_ret;\n\n");
+ outputf(outc,
+ "\tduk_ret_t get_ret;\n\n");
- fprintf(outf,
+ outputf(outc,
"\tget_ret = %s_%s_%s_getter(ctx);\n",
DLPFX, interfacee->class_name, atributee->name);
- fprintf(outf,
+ outputf(outc,
"\tif (get_ret != 1) {\n"
"\t\treturn 0;\n"
"\t}\n\n"
@@ -1292,46 +1445,49 @@ output_putforwards_setter(FILE* outf,
"\t/* ... attribute parameter */\n\n"
"\t/* call the putforward */\n");
- fprintf(outf,
+ outputf(outc,
"\tduk_put_prop_string(ctx, -2, \"%s\");\n\n",
atributee->putforwards);
- fprintf(outf,
+ outputf(outc,
"\treturn 0;\n");
return 0;
}
+
/**
* Generate class property setter for a single attribute
*/
static int
-output_attribute_setter(FILE* outf,
+output_attribute_setter(struct opctx *outc,
struct ir_entry *interfacee,
struct ir_attribute_entry *atributee)
{
int res = -1;
/* setter definition */
- fprintf(outf,
+ outputf(outc,
"static duk_ret_t %s_%s_%s_setter(duk_context *ctx)\n",
DLPFX, interfacee->class_name, atributee->name);
- fprintf(outf,"{\n");
+ outputf(outc,
+ "{\n");
- output_get_method_private(outf, interfacee->class_name,
+ output_get_method_private(outc,
+ interfacee->class_name,
interfacee->u.interface.primary_global);
/* if binding available for this attribute getter process it */
if (atributee->setter != NULL) {
- res = output_ccode(outf, atributee->setter);
+ res = output_ccode(outc, atributee->setter);
if (res == 0) {
/* no code provided for this setter so generate */
- res = output_generated_attribute_setter(outf,
+ res = output_generated_attribute_setter(outc,
interfacee,
atributee);
}
} else if (atributee->putforwards != NULL) {
- res = output_putforwards_setter(outf,
+ res = output_putforwards_setter(outc,
interfacee,
atributee);
}
@@ -1354,14 +1510,17 @@ output_attribute_setter(FILE* outf,
atributee->name,
type_str);
if (options->dbglog) {
- fprintf(outf, "\tNSLOG(dukky, WARNING, \"Unimplemented\");\n" );
+ outputf(outc,
+ "\tNSLOG(dukky, WARNING, \"Unimplemented\");\n");
}
/* no implementation so generate default */
- fprintf(outf, "\treturn 0;\n");
+ outputf(outc,
+ "\treturn 0;\n");
}
- fprintf(outf, "}\n\n");
+ outputf(outc,
+ "}\n\n");
return res;
}
@@ -1371,7 +1530,7 @@ output_attribute_setter(FILE* outf,
* Generate class property getter/setter for a single attribute
*/
static int
-output_interface_attribute(FILE* outf,
+output_interface_attribute(struct opctx *outc,
struct ir_entry *interfacee,
struct ir_attribute_entry *atributee)
{
@@ -1381,28 +1540,29 @@ output_interface_attribute(FILE* outf,
atributee->property_name = gen_idl2c_name(atributee->name);
}
- res = output_attribute_getter(outf, interfacee, atributee);
+ res = output_attribute_getter(outc, interfacee, atributee);
/* only read/write and putforward attributes have a setter */
if ((atributee->modifier != WEBIDL_TYPE_MODIFIER_READONLY) ||
(atributee->putforwards != NULL)) {
- res = output_attribute_setter(outf, interfacee, atributee);
+ res = output_attribute_setter(outc, interfacee, atributee);
}
return res;
}
+
/**
* generate class property getters and setters for each interface attribute
*/
static int
-output_interface_attributes(FILE* outf, struct ir_entry *ife)
+output_interface_attributes(struct opctx *outc, struct ir_entry *ife)
{
int attrc;
for (attrc = 0; attrc < ife->u.interface.attributec; attrc++) {
output_interface_attribute(
- outf,
+ outc,
ife,
ife->u.interface.attributev + attrc);
}
@@ -1411,104 +1571,111 @@ output_interface_attributes(FILE* outf, struct ir_entry *ife)
}
-/* exported interface documented in duk-libdom.h */
+/*
+ * generate a source file to implement an interface using duk and libdom.
+ *
+ * exported interface documented in duk-libdom.h
+ */
int output_interface(struct ir *ir, struct ir_entry *interfacee)
{
- FILE *ifacef;
+ struct opctx *ifop;
struct ir_entry *inherite;
int res = 0;
- /* open output file */
- ifacef = genb_fopen_tmp(interfacee->filename);
- if (ifacef == NULL) {
- return -1;
+ /* open the output */
+ res = output_open(interfacee->filename, &ifop);
+ if (res !=0 ) {
+ return res;
}
/* find parent interface entry */
inherite = ir_inherit_entry(ir, interfacee);
/* tool preface */
- output_tool_preface(ifacef);
+ output_tool_preface(ifop);
/* binding preface */
- output_method_cdata(ifacef,
+ output_method_cdata(ifop,
ir->binding_node,
GENBIND_METHOD_TYPE_PREFACE);
/* class preface */
- output_method_cdata(ifacef,
+ output_method_cdata(ifop,
interfacee->class,
GENBIND_METHOD_TYPE_PREFACE);
/* tool prologue */
- output_tool_prologue(ifacef);
+ output_tool_prologue(ifop);
/* binding prologue */
- output_method_cdata(ifacef,
+ output_method_cdata(ifop,
ir->binding_node,
GENBIND_METHOD_TYPE_PROLOGUE);
/* class prologue */
- output_method_cdata(ifacef,
+ output_method_cdata(ifop,
interfacee->class,
GENBIND_METHOD_TYPE_PROLOGUE);
- fprintf(ifacef, "\n");
+ outputf(ifop,
+ "\n");
/* initialisor */
- res = output_interface_init(ifacef, interfacee, inherite);
+ res = output_interface_init(ifop, interfacee, inherite);
if (res != 0) {
goto op_error;
}
/* finaliser */
- output_interface_fini(ifacef, interfacee, inherite);
+ output_interface_fini(ifop, interfacee, inherite);
/* constructor */
- output_interface_constructor(ifacef, interfacee);
+ output_interface_constructor(ifop, interfacee);
/* destructor */
- output_interface_destructor(ifacef, interfacee);
+ output_interface_destructor(ifop, interfacee);
/* operations */
- output_interface_operations(ifacef, interfacee);
+ output_interface_operations(ifop, interfacee);
/* attributes */
- output_interface_attributes(ifacef, interfacee);
+ output_interface_attributes(ifop, interfacee);
/* prototype */
- output_interface_prototype(ifacef, ir, interfacee, inherite);
+ output_interface_prototype(ifop, ir, interfacee, inherite);
- fprintf(ifacef, "\n");
+ outputf(ifop, "\n");
/* class epilogue */
- output_method_cdata(ifacef,
+ output_method_cdata(ifop,
interfacee->class,
GENBIND_METHOD_TYPE_EPILOGUE);
/* binding epilogue */
- output_method_cdata(ifacef,
+ output_method_cdata(ifop,
ir->binding_node,
GENBIND_METHOD_TYPE_EPILOGUE);
/* class postface */
- output_method_cdata(ifacef,
+ output_method_cdata(ifop,
interfacee->class,
GENBIND_METHOD_TYPE_POSTFACE);
/* binding postface */
- output_method_cdata(ifacef,
+ output_method_cdata(ifop,
ir->binding_node,
GENBIND_METHOD_TYPE_POSTFACE);
op_error:
- genb_fclose_tmp(ifacef, interfacee->filename);
+ output_close(ifop);
return res;
}
+
/* exported function documented in duk-libdom.h */
-int output_interface_declaration(FILE* outf, struct ir_entry *interfacee)
+int
+output_interface_declaration(struct opctx *outc, struct ir_entry *interfacee)
{
struct genbind_node *init_node;
@@ -1520,7 +1687,8 @@ int output_interface_declaration(FILE* outf, struct ir_entry *interfacee)
}
/* prototype declaration */
- fprintf(outf, "duk_ret_t %s_%s___proto(duk_context *ctx, void *udata);\n",
+ outputf(outc,
+ "duk_ret_t %s_%s___proto(duk_context *ctx, void *udata);\n",
DLPFX, interfacee->class_name);
/* if the interface has no references (no other interface inherits from
@@ -1528,13 +1696,13 @@ int output_interface_declaration(FILE* outf, struct ir_entry *interfacee)
* other class constructor/destructor should call them.
*/
if (interfacee->refcount < 1) {
- fprintf(outf, "\n");
-
+ outputf(outc,
+ "\n");
return 0;
}
/* finaliser declaration */
- fprintf(outf,
+ outputf(outc,
"void %s_%s___fini(duk_context *ctx, %s_private_t *priv);\n",
DLPFX, interfacee->class_name, interfacee->class_name);
@@ -1544,9 +1712,10 @@ int output_interface_declaration(FILE* outf, struct ir_entry *interfacee)
GENBIND_METHOD_TYPE_INIT);
/* initialisor definition */
- output_interface_init_declaration(outf, interfacee, init_node);
+ output_interface_init_declaration(outc, interfacee, init_node);
- fprintf(outf, ";\n\n");
+ outputf(outc,
+ ";\n\n");
return 0;
}
diff --git a/src/duk-libdom.c b/src/duk-libdom.c
index a04ee7d..6cb2815 100644
--- a/src/duk-libdom.c
+++ b/src/duk-libdom.c
@@ -20,6 +20,7 @@
#include "nsgenbind-ast.h"
#include "webidl-ast.h"
#include "ir.h"
+#include "output.h"
#include "duk-libdom.h"
/** prefix for all generated functions */
@@ -52,58 +53,53 @@ static char *get_prototype_name(const char *interface_name)
-static FILE *open_header(struct ir *ir, const char *name)
+static struct opctx *open_header(struct ir *ir, const char *name)
{
- FILE *hdrf;
char *fname;
int fnamel;
+ struct opctx *hdrc;
+ int res;
fnamel = strlen(name) + 4;
fname = malloc(fnamel);
snprintf(fname, fnamel, "%s.h", name);
- /* open output file */
- hdrf = genb_fopen_tmp(fname);
+ /* open the output header file */
+ res = output_open(fname, &hdrc);
free(fname);
- if (hdrf == NULL) {
+ if (res != 0 ) {
return NULL;
}
/* tool preface */
- output_tool_preface(hdrf);
+ output_tool_preface(hdrc);
/* binding preface */
- output_method_cdata(hdrf,
+ output_method_cdata(hdrc,
ir->binding_node,
GENBIND_METHOD_TYPE_PREFACE);
/* header guard */
- fprintf(hdrf, "\n#ifndef %s_%s_h\n", DLPFX, name);
- fprintf(hdrf, "#define %s_%s_h\n\n", DLPFX, name);
+ outputf(hdrc,
+ "\n#ifndef %s_%s_h\n", DLPFX, name);
+ outputf(hdrc,
+ "#define %s_%s_h\n\n", DLPFX, name);
- return hdrf;
+ return hdrc;
}
-static int close_header(struct ir *ir,
- FILE *hdrf,
- const char *name)
+static int close_header(struct ir *ir, struct opctx *hdrc)
{
- char *fname;
- int fnamel;
-
- fnamel = strlen(name) + 4;
- fname = malloc(fnamel);
- snprintf(fname, fnamel, "%s.h", name);
-
- fprintf(hdrf, "\n#endif\n");
+ /* close header guard */
+ outputf(hdrc,
+ "\n#endif\n");
/* binding postface */
- output_method_cdata(hdrf,
+ output_method_cdata(hdrc,
ir->binding_node,
GENBIND_METHOD_TYPE_POSTFACE);
- genb_fclose_tmp(hdrf, fname);
- free(fname);
+ output_close(hdrc);
return 0;
}
@@ -116,10 +112,10 @@ static int
output_private_header(struct ir *ir)
{
int idx;
- FILE *privf;
+ struct opctx *privc;
/* open header */
- privf = open_header(ir, "private");
+ privc = open_header(ir, "private");
for (idx = 0; idx < ir->entryc; idx++) {
struct ir_entry *interfacee;
@@ -138,24 +134,26 @@ output_private_header(struct ir *ir)
switch (interfacee->type) {
case IR_ENTRY_TYPE_INTERFACE:
- fprintf(privf,
+ outputf(privc,
"/* Private data for %s interface */\n",
interfacee->name);
break;
case IR_ENTRY_TYPE_DICTIONARY:
- fprintf(privf,
+ outputf(privc,
"/* Private data for %s dictionary */\n",
interfacee->name);
break;
}
- fprintf(privf, "typedef struct {\n");
+ outputf(privc,
+ "typedef struct {\n");
/* find parent entry and include in private */
inherite = ir_inherit_entry(ir, interfacee);
if (inherite != NULL) {
- fprintf(privf, "\t%s_private_t parent;\n",
+ outputf(privc,
+ "\t%s_private_t parent;\n",
inherite->class_name);
}
@@ -165,11 +163,11 @@ output_private_header(struct ir *ir)
NULL,
GENBIND_NODE_TYPE_PRIVATE);
while (priv_node != NULL) {
- fprintf(privf, "\t");
+ outputc(privc, '\t');
- output_ctype(privf, priv_node, true);
+ output_ctype(privc, priv_node, true);
- fprintf(privf, ";\n");
+ outputf(privc, ";\n");
priv_node = genbind_node_find_type(
genbind_node_getnode(interfacee->class),
@@ -177,11 +175,12 @@ output_private_header(struct ir *ir)
GENBIND_NODE_TYPE_PRIVATE);
}
- fprintf(privf, "} __attribute__((aligned)) %s_private_t;\n\n", interfacee->class_name);
-
+ outputf(privc,
+ "} __attribute__((aligned)) %s_private_t;\n\n",
+ interfacee->class_name);
}
- close_header(ir, privf, "private");
+ close_header(ir, privc);
return 0;
}
@@ -193,10 +192,10 @@ static int
output_prototype_header(struct ir *ir)
{
int idx;
- FILE *protof;
+ struct opctx *protoc;
/* open header */
- protof = open_header(ir, "prototype");
+ protoc = open_header(ir, "prototype");
for (idx = 0; idx < ir->entryc; idx++) {
struct ir_entry *entry;
@@ -205,16 +204,16 @@ output_prototype_header(struct ir *ir)
switch (entry->type) {
case IR_ENTRY_TYPE_INTERFACE:
- output_interface_declaration(protof, entry);
+ output_interface_declaration(protoc, entry);
break;
case IR_ENTRY_TYPE_DICTIONARY:
- output_dictionary_declaration(protof, entry);
+ output_dictionary_declaration(protoc, entry);
break;
}
}
- close_header(ir, protof, "prototype");
+ close_header(ir, protoc);
return 0;
}
@@ -271,12 +270,12 @@ output_makefile(struct ir *ir)
static int
output_binding_header(struct ir *ir)
{
- FILE *bindf;
+ struct opctx *bindc;
/* open header */
- bindf = open_header(ir, "binding");
+ bindc = open_header(ir, "binding");
- fprintf(bindf,
+ outputf(bindc,
"#define _MAGIC(S) (\"%s\" S)\n"
"#define MAGIC(S) _MAGIC(#S)\n"
"#define PROTO_MAGIC MAGIC(PROTOTYPES)\n"
@@ -291,7 +290,7 @@ output_binding_header(struct ir *ir)
MAGICPFX);
/* declaration of constant string values */
- fprintf(bindf,
+ outputf(bindc,
"/* Constant strings */\n"
"extern const char *%s_error_fmt_argument;\n"
"extern const char *%s_error_fmt_bool_type;\n"
@@ -301,14 +300,14 @@ output_binding_header(struct ir *ir)
"\n",
DLPFX, DLPFX, DLPFX, DLPFX, DLPFX);
- fprintf(bindf,
+ outputf(bindc,
"duk_bool_t %s_instanceof(duk_context *ctx, duk_idx_t index, const char *klass);\n",
DLPFX);
- fprintf(bindf,
+ outputf(bindc,
"duk_ret_t %s_create_prototypes(duk_context *ctx);\n", DLPFX);
- close_header(ir, bindf, "binding");
+ close_header(ir, bindc);
return 0;
}
@@ -324,54 +323,55 @@ static int
output_binding_src(struct ir *ir)
{
int idx;
- FILE *bindf;
struct ir_entry *pglobale = NULL;
char *proto_name;
+ struct opctx *bindc;
+ int res;
- /* open output file */
- bindf = genb_fopen_tmp("binding.c");
- if (bindf == NULL) {
+ /* open the output binding file */
+ res = output_open("binding.c", &bindc);
+ if (res != 0 ) {
return -1;
}
/* tool preface */
- output_tool_preface(bindf);
+ output_tool_preface(bindc);
/* binding preface */
- output_method_cdata(bindf,
+ output_method_cdata(bindc,
ir->binding_node,
GENBIND_METHOD_TYPE_PREFACE);
/* tool prologue */
- output_tool_prologue(bindf);
+ output_tool_prologue(bindc);
/* binding prologue */
- output_method_cdata(bindf,
+ output_method_cdata(bindc,
ir->binding_node,
GENBIND_METHOD_TYPE_PROLOGUE);
- fprintf(bindf, "\n");
+ outputc(bindc, '\n');
- fprintf(bindf,
+ outputf(bindc,
"/* Error format strings */\n"
"const char *%s_error_fmt_argument =\"%%d argument required, but ony %%d present.\";\n"
"const char *%s_error_fmt_bool_type =\"argument %%d (%%s) requires a bool\";\n"
"const char *%s_error_fmt_number_type =\"argument %%d (%%s) requires a number\";\n",
DLPFX, DLPFX, DLPFX);
- fprintf(bindf, "\n");
+ outputf(bindc, "\n");
- fprintf(bindf,
+ outputf(bindc,
"/* Magic identifiers */\n"
"const char *%s_magic_string_private =\"%sPRIVATE\";\n"
"const char *%s_magic_string_prototypes =\"%sPROTOTYPES\";\n",
DLPFX, MAGICPFX, DLPFX, MAGICPFX);
- fprintf(bindf, "\n");
+ outputf(bindc, "\n");
/* instanceof helper */
- fprintf(bindf,
+ outputf(bindc,
"duk_bool_t\n"
"%s_instanceof(duk_context *ctx, duk_idx_t _idx, const char *klass)\n"
"{\n"
@@ -406,7 +406,7 @@ output_binding_src(struct ir *ir)
DLPFX, DLPFX);
/* prototype creation helper function */
- fprintf(bindf,
+ outputf(bindc,
"static duk_ret_t\n"
"%s_to_string(duk_context *ctx)\n"
"{\n"
@@ -431,10 +431,10 @@ output_binding_src(struct ir *ir)
DLPFX,
MAGICPFX);
- fprintf(bindf,
+ outputf(bindc,
"static duk_ret_t %s_create_prototype(duk_context *ctx,\n",
DLPFX);
- fprintf(bindf,
+ outputf(bindc,
"\t\t\t\t\tduk_safe_call_function genproto,\n"
"\t\t\t\t\tconst char *proto_name,\n"
"\t\t\t\t\tconst char *klass_name)\n"
@@ -460,10 +460,10 @@ output_binding_src(struct ir *ir)
DLPFX);
/* generate prototype creation */
- fprintf(bindf,
+ outputf(bindc,
"duk_ret_t %s_create_prototypes(duk_context *ctx)\n", DLPFX);
- fprintf(bindf, "{\n");
+ outputf(bindc, "{\n");
for (idx = 0; idx < ir->entryc; idx++) {
struct ir_entry *interfacee;
@@ -489,7 +489,7 @@ output_binding_src(struct ir *ir)
}
proto_name = get_prototype_name(interfacee->name);
- fprintf(bindf,
+ outputf(bindc,
"\t%s_create_prototype(ctx, %s_%s___proto, \"%s\", \"%s\");\n",
DLPFX,
DLPFX,
@@ -501,10 +501,10 @@ output_binding_src(struct ir *ir)
}
if (pglobale != NULL) {
- fprintf(bindf, "\n\t/* Global object prototype is last */\n");
+ outputf(bindc, "\n\t/* Global object prototype is last */\n");
proto_name = get_prototype_name(pglobale->name);
- fprintf(bindf,
+ outputf(bindc,
"\t%s_create_prototype(ctx, %s_%s___proto, \"%s\", \"%s\");\n",
DLPFX,
DLPFX,
@@ -514,16 +514,16 @@ output_binding_src(struct ir *ir)
free(proto_name);
}
- fprintf(bindf, "\n\treturn DUK_ERR_NONE;\n");
+ outputf(bindc, "\n\treturn DUK_ERR_NONE;\n");
- fprintf(bindf, "}\n");
+ outputf(bindc, "}\n");
/* binding postface */
- output_method_cdata(bindf,
+ output_method_cdata(bindc,
ir->binding_node,
GENBIND_METHOD_TYPE_POSTFACE);
- genb_fclose_tmp(bindf, "binding.c");
+ output_close(bindc);
return 0;
}
diff --git a/src/duk-libdom.h b/src/duk-libdom.h
index 51d4327..37a9825 100644
--- a/src/duk-libdom.h
+++ b/src/duk-libdom.h
@@ -16,33 +16,36 @@ int duk_libdom_output(struct ir *ir);
/**
* generate a source file to implement an interface using duk and libdom.
+ *
+ * \param ir The intermediate representation of the binding tree.
+ * \param interfacee The interface entry to output within the ir.
*/
int output_interface(struct ir *ir, struct ir_entry *interfacee);
/**
- * generate a declaration to implement a dictionary using duk and libdom.
+ * generate a source file to implement a dictionary using duk and libdom.
*/
-int output_interface_declaration(FILE* outf, struct ir_entry *interfacee);
+int output_dictionary(struct ir *ir, struct ir_entry *dictionarye);
/**
- * generate a source file to implement a dictionary using duk and libdom.
+ * generate a declaration to implement a dictionary using duk and libdom.
*/
-int output_dictionary(struct ir *ir, struct ir_entry *dictionarye);
+int output_interface_declaration(struct opctx *outc, struct ir_entry *interfacee);
/**
* generate a declaration to implement a dictionary using duk and libdom.
*/
-int output_dictionary_declaration(FILE* outf, struct ir_entry *dictionarye);
+int output_dictionary_declaration(struct opctx *outc, struct ir_entry *dictionarye);
/**
* generate preface block for nsgenbind
*/
-int output_tool_preface(FILE* outf);
+int output_tool_preface(struct opctx *outc);
/**
* generate preface block for nsgenbind
*/
-int output_tool_prologue(FILE* outf);
+int output_tool_prologue(struct opctx *outc);
/**
* output character data of node of given type.
@@ -54,7 +57,7 @@ int output_tool_prologue(FILE* outf);
* \param nodetype the type of child node to search for.
* \return The number of nodes written or 0 for none.
*/
-int output_cdata(FILE* outf, struct genbind_node *node, enum genbind_node_type nodetype);
+int output_cdata(struct opctx *outc, struct genbind_node *node, enum genbind_node_type nodetype);
/**
@@ -67,7 +70,7 @@ int output_cdata(FILE* outf, struct genbind_node *node, enum genbind_node_type n
* \param nodetype the type of child node to search for.
* \return The number of nodes written or 0 for none.
*/
-int output_ccode(FILE* outf, struct genbind_node *node);
+int output_ccode(struct opctx *outc, struct genbind_node *node);
/**
* output character data of method node of given type.
@@ -79,7 +82,7 @@ int output_ccode(FILE* outf, struct genbind_node *node);
* \param nodetype the type of child node to search for.
* \return The number of nodes written or 0 for none.
*/
-int output_method_cdata(FILE* outf, struct genbind_node *node, enum genbind_method_type sel_method_type);
+int output_method_cdata(struct opctx *outc, struct genbind_node *node, enum genbind_method_type sel_method_type);
/**
* output a C variable type
@@ -94,7 +97,7 @@ int output_method_cdata(FILE* outf, struct genbind_node *node, enum genbind_meth
* \param identifier If the indentifier should be output.
* \return 0 on success.
*/
-int output_ctype(FILE *outf, struct genbind_node *node, bool identifier);
+int output_ctype(struct opctx *outc, struct genbind_node *node, bool identifier);
/**
* Generate a C name from an IDL name.
@@ -114,12 +117,12 @@ char *gen_idl2c_name(const char *idlname);
/**
* Generate class property setter for a single attribute.
*/
-int output_generated_attribute_setter(FILE* outf, struct ir_entry *interfacee, struct ir_attribute_entry *atributee);
+int output_generated_attribute_setter(struct opctx *outc, struct ir_entry *interfacee, struct ir_attribute_entry *atributee);
/**
* Generate class property getter for a single attribute.
*/
-int output_generated_attribute_getter(FILE* outf, struct ir_entry *interfacee, struct ir_attribute_entry *atributee);
+int output_generated_attribute_getter(struct opctx *outc, struct ir_entry *interfacee, struct ir_attribute_entry *atributee);
#endif
diff --git a/src/nsgenbind.c b/src/nsgenbind.c
index 58d62cb..73b9673 100644
--- a/src/nsgenbind.c
+++ b/src/nsgenbind.c
@@ -18,6 +18,7 @@
#include "nsgenbind-ast.h"
#include "webidl-ast.h"
#include "ir.h"
+#include "output.h"
#include "jsapi-libdom.h"
#include "duk-libdom.h"
diff --git a/src/output.c b/src/output.c
new file mode 100644
index 0000000..84579f2
--- /dev/null
+++ b/src/output.c
@@ -0,0 +1,106 @@
+/* generated output implementation
+ *
+ * This file is part of nsgenbind.
+ * Licensed under the MIT License,
+ * http://www.opensource.org/licenses/mit-license.php
+ * Copyright 2019 Vincent Sanders <vince@netsurf-browser.org>
+ */
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "utils.h"
+#include "output.h"
+
+struct opctx {
+ char *filename;
+ FILE *outf;
+ unsigned int lineno;
+};
+
+int output_open(const char *filename, struct opctx **opctx_out)
+{
+ struct opctx *opctx;
+
+ opctx = malloc(sizeof(struct opctx));
+ if (opctx == NULL) {
+ return -1;
+ }
+
+ opctx->filename = strdup(filename);
+ if (opctx->filename == NULL) {
+ free(opctx);
+ return -1;
+ }
+
+ /* open output file */
+ opctx->outf = genb_fopen_tmp(opctx->filename);
+ if (opctx->outf == NULL) {
+ free(opctx->filename);
+ free(opctx);
+ return -1;
+ }
+
+ opctx->lineno = 2;
+ *opctx_out = opctx;
+
+ return 0;
+}
+
+int output_close(struct opctx *opctx)
+{
+ int res;
+ res = genb_fclose_tmp(opctx->outf, opctx->filename);
+ free(opctx->filename);
+ free(opctx);
+ return res;
+}
+
+/**
+ * buffer to hold formatted output so newlines can be counted
+ */
+static char output_buffer[128*1024];
+
+int outputf(struct opctx *opctx, const char *fmt, ...)
+{
+ va_list ap;
+ int res;
+ int idx;
+
+ va_start(ap, fmt);
+ res = vsnprintf(output_buffer, sizeof(output_buffer), fmt, ap);
+ va_end(ap);
+
+ /* account for newlines in output */
+ for (idx = 0; idx < res; idx++) {
+ if (output_buffer[idx] == '\n') {
+ opctx->lineno++;
+ }
+ }
+
+ fwrite(output_buffer, 1, res, opctx->outf);
+
+ return res;
+}
+
+int outputc(struct opctx *opctx, int c)
+{
+ if (c == '\n') {
+ opctx->lineno++;
+ }
+ fputc(c, opctx->outf);
+
+ return 0;
+}
+
+int output_line(struct opctx *opctx)
+{
+ int res;
+ res = fprintf(opctx->outf,
+ "#line %d \"%s\"\n",
+ opctx->lineno, opctx->filename);
+ opctx->lineno++;
+ return res;
+}
diff --git a/src/output.h b/src/output.h
new file mode 100644
index 0000000..0423feb
--- /dev/null
+++ b/src/output.h
@@ -0,0 +1,42 @@
+/* generated output handlers
+ *
+ * This file is part of nsgenbind.
+ * Licensed under the MIT License,
+ * http://www.opensource.org/licenses/mit-license.php
+ * Copyright 2012 Vincent Sanders <vince@netsurf-browser.org>
+ */
+
+#ifndef nsgenbind_output_h
+#define nsgenbind_output_h
+
+struct opctx;
+
+/**
+ * open output file
+ *
+ * opens output file and creates output context
+ *
+ * \param filename The filename of the file to output
+ * \param opctx_out The resulting output context
+ * \return 0 on success and opctx_out updated else -1
+ */
+int output_open(const char *filename, struct opctx **opctx_out);
+
+/**
+ * close output file and free context
+ */
+int output_close(struct opctx *opctx);
+
+/**
+ * output formatted data to file
+ */
+int outputf(struct opctx *opctx, const char *fmt, ...) __attribute__ ((format (printf, 2, 3)));
+
+int outputc(struct opctx *opctx, int c);
+
+/**
+ * generate c comment with line directive for current outut context
+ */
+int output_line(struct opctx *opctx);
+
+#endif