From e87ed9a82296b8481b0d867e41bbfb65ea5fae9f Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Thu, 5 Nov 2015 23:56:35 +0000 Subject: Use attribute types from IR for generated event handlers --- src/duk-libdom-generated.c | 144 ++++++++++++++++++++++++++++++++++++++++----- src/duk-libdom-interface.c | 25 ++++++-- 2 files changed, 149 insertions(+), 20 deletions(-) diff --git a/src/duk-libdom-generated.c b/src/duk-libdom-generated.c index cf70758..e40c43e 100644 --- a/src/duk-libdom-generated.c +++ b/src/duk-libdom-generated.c @@ -28,13 +28,60 @@ #include "ir.h" #include "duk-libdom.h" +static int +output_generated_attribute_user_getter(FILE* outf, + struct ir_entry *interfacee, + struct ir_attribute_entry *atributee) +{ + interfacee = interfacee; + + if ((atributee->typev[0].name != NULL) && + strcmp(atributee->typev[0].name, "EventHandler") == 0) { + + /* this can generate for onxxx event handlers */ + if ((atributee->name[0] != 'o') || + (atributee->name[1] != 'n')) { + return -1; /* not onxxx */ + } + + fprintf(outf, + "\tdom_event_target *et = (dom_event_target *)(((node_private_t *)priv)->node);\n" + "\tdom_string *name;\n" + "\tdom_exception exc;\n\n" + "\texc = dom_string_create((const uint8_t *)\"%s\", %ld, &name);\n" + "\tif (exc != DOM_NO_ERR) return 0;\n\n" + "\tduk_push_this(ctx);\n" + "\t/* ... node */\n" + "\tif (dukky_get_current_value_of_event_handler(ctx, name, et) == false) {\n" + "\t\tdom_string_unref(name);\n" + "\t\treturn 0;\n" + "\t}\n" + "\tdom_string_unref(name);\n" + "\t/* ... handler node */\n" + "\tduk_pop(ctx);\n" + "\t/* ... handler */\n" + "\treturn 1;\n", + atributee->name + 2, + strlen(atributee->name + 2)); + return 0; + } + return -1; +} + /* exported function documented in duk-libdom.h */ int output_generated_attribute_getter(FILE* outf, struct ir_entry *interfacee, struct ir_attribute_entry *atributee) { - switch (atributee->base_type) { + int res = 0; + + /* generation can only cope with a single type on the attribute */ + if (atributee->typec != 1) { + return -1; + } + + switch (atributee->typev[0].base) { case WEBIDL_TYPE_STRING: fprintf(outf, "\tdom_exception exc;\n" @@ -59,7 +106,7 @@ output_generated_attribute_getter(FILE* outf, break; case WEBIDL_TYPE_LONG: - if (atributee->type_modifier == WEBIDL_TYPE_MODIFIER_UNSIGNED) { + if (atributee->typev[0].modifier == WEBIDL_TYPE_MODIFIER_UNSIGNED) { fprintf(outf, "\tdom_ulong l;\n"); } else { fprintf(outf, "\tdom_long l;\n"); @@ -83,7 +130,7 @@ output_generated_attribute_getter(FILE* outf, break; case WEBIDL_TYPE_SHORT: - if (atributee->type_modifier == WEBIDL_TYPE_MODIFIER_UNSIGNED) { + if (atributee->typev[0].modifier == WEBIDL_TYPE_MODIFIER_UNSIGNED) { fprintf(outf, "\tdom_ushort s;\n"); } else { fprintf(outf, "\tdom_short s;\n"); @@ -126,25 +173,81 @@ output_generated_attribute_getter(FILE* outf, "\treturn 1;\n"); break; + case WEBIDL_TYPE_USER: + res = output_generated_attribute_user_getter(outf, + interfacee, + atributee); + break; + default: - return -1; + res = -1; + break; } - WARN(WARNING_GENERATED, - "Generated: getter %s::%s();", - interfacee->name, atributee->name); + if (res >= 0) { + WARN(WARNING_GENERATED, + "Generated: getter %s::%s();", + interfacee->name, atributee->name); + } + + return res; +} + +static int +output_generated_attribute_user_setter(FILE* outf, + struct ir_entry *interfacee, + struct ir_attribute_entry *atributee) +{ + interfacee = interfacee; - return 0; + if ((atributee->typev[0].name != NULL) && + strcmp(atributee->typev[0].name, "EventHandler") == 0) { + + /* this can generate for onxxx event handlers */ + if ((atributee->name[0] != 'o') || + (atributee->name[1] != 'n')) { + return -1; /* not onxxx */ + } + + fprintf(outf, + "\t/* handlerfn */\n" + "\tduk_push_this(ctx);\n" + "\t/* handlerfn this */\n" + "\tduk_get_prop_string(ctx, -1, HANDLER_MAGIC);\n" + "\t/* handlerfn this handlers */\n" + "\tduk_push_lstring(ctx, \"%s\", %ld);\n" + "\t/* handlerfn this handlers click */\n" + "\tduk_dup(ctx, -4);\n" + "\t/* handlerfn this handlers click handlerfn */\n" + "\tduk_put_prop(ctx, -3);\n" + "\t/* handlerfn this handlers */\n" + "\tdukky_register_event_listener_for(ctx,\n" + "\t\t(dom_element *)((node_private_t *)priv)->node,\n" + "\t\tcorestring_dom_click);\n" + "\treturn 0;\n", + atributee->name + 2, + strlen(atributee->name + 2)); + return 0; + } + return -1; } + /* exported function documented in duk-libdom.h */ int output_generated_attribute_setter(FILE* outf, struct ir_entry *interfacee, struct ir_attribute_entry *atributee) { - switch (atributee->base_type) { + int res = 0; + + /* generation can only cope with a single type on the attribute */ + if (atributee->typec != 1) { + return -1; + } + + switch (atributee->typev[0].base) { case WEBIDL_TYPE_STRING: fprintf(outf, "\tdom_exception exc;\n" @@ -173,7 +276,7 @@ output_generated_attribute_setter(FILE* outf, break; case WEBIDL_TYPE_LONG: - if (atributee->type_modifier == WEBIDL_TYPE_MODIFIER_UNSIGNED) { + if (atributee->typev[0].modifier == WEBIDL_TYPE_MODIFIER_UNSIGNED) { fprintf(outf, "\tdom_exception exc;\n" "\tdom_ulong l;\n" @@ -202,7 +305,7 @@ output_generated_attribute_setter(FILE* outf, break; case WEBIDL_TYPE_SHORT: - if (atributee->type_modifier == WEBIDL_TYPE_MODIFIER_UNSIGNED) { + if (atributee->typev[0].modifier == WEBIDL_TYPE_MODIFIER_UNSIGNED) { fprintf(outf, "\tdom_exception exc;\n" "\tdom_ushort s;\n" @@ -250,14 +353,23 @@ output_generated_attribute_setter(FILE* outf, "\treturn 0;\n"); break; + case WEBIDL_TYPE_USER: + res = output_generated_attribute_user_setter(outf, + interfacee, + atributee); + break; + default: - return -1; + res = -1; + break; } - WARN(WARNING_GENERATED, - "Generated: getter %s::%s();", - interfacee->name, atributee->name); + if (res >= 0) { + WARN(WARNING_GENERATED, + "Generated: getter %s::%s();", + interfacee->name, atributee->name); + } - return 0; + return res; } diff --git a/src/duk-libdom-interface.c b/src/duk-libdom-interface.c index d7214e3..8741815 100644 --- a/src/duk-libdom-interface.c +++ b/src/duk-libdom-interface.c @@ -1231,13 +1231,21 @@ output_attribute_getter(FILE* outf, } /* no implementation so generate default and warnings if required */ + const char *type_str; + if (atributee->typec == 0) { + type_str = ""; + } else if (atributee->typec == 1) { + type_str = webidl_type_to_str(atributee->typev[0].modifier, + atributee->typev[0].base); + } else { + type_str = "multiple"; + } WARN(WARNING_UNIMPLEMENTED, "Unimplemented: getter %s::%s(%s);", interfacee->name, atributee->name, - webidl_type_to_str(atributee->type_modifier, - atributee->base_type)); + type_str); if (options->dbglog) { fprintf(outf, "\tLOG(\"Unimplemented\");\n" ); @@ -1321,12 +1329,21 @@ output_attribute_setter(FILE* outf, /* implementation not generated from any other source */ if (res < 0) { + const char *type_str; + if (atributee->typec == 0) { + type_str = ""; + } else if (atributee->typec == 1) { + type_str = webidl_type_to_str( + atributee->typev[0].modifier, + atributee->typev[0].base); + } else { + type_str = "multiple"; + } WARN(WARNING_UNIMPLEMENTED, "Unimplemented: setter %s::%s(%s);", interfacee->name, atributee->name, - webidl_type_to_str(atributee->type_modifier, - atributee->base_type)); + type_str); if (options->dbglog) { fprintf(outf, "\tLOG(\"Unimplemented\");\n" ); } -- cgit v1.2.3