From e031876dd52c9d789ec5a3e41156d99962126c2e Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Fri, 3 May 2019 17:29:45 +0100 Subject: Make file output use a common interface Signed-off-by: Vincent Sanders --- src/duk-libdom-interface.c | 905 +++++++++++++++++++++++++++------------------ 1 file changed, 537 insertions(+), 368 deletions(-) (limited to 'src/duk-libdom-interface.c') 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,85 +28,133 @@ #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; } -/** - * 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; } -- cgit v1.2.3