diff options
-rw-r--r-- | src/duk-libdom-interface.c | 262 | ||||
-rw-r--r-- | src/ir.c | 16 | ||||
-rw-r--r-- | src/ir.h | 13 |
3 files changed, 241 insertions, 50 deletions
diff --git a/src/duk-libdom-interface.c b/src/duk-libdom-interface.c index 940292e..34a0db0 100644 --- a/src/duk-libdom-interface.c +++ b/src/duk-libdom-interface.c @@ -1193,34 +1193,181 @@ output_interface_operations(FILE* outf, struct ir_entry *ife) /** - * Generate class property setter for a single attribute + * Generate class property getter for a single attribute */ static int -output_attribute_setter(FILE* outf, +output_generated_attribute_getter(FILE* outf, + struct ir_entry *interfacee, + struct ir_attribute_entry *atributee) +{ + switch (atributee->base_type) { + case WEBIDL_TYPE_STRING: + fprintf(outf, + "\tdom_exception exc;\n" + "\tdom_string *str;\n" + "\n"); + fprintf(outf, + "\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, + "\tif (exc != DOM_NO_ERR) {\n" + "\t\treturn 0;\n" + "\t}\n" + "\n" + "\tduk_push_lstring(ctx,\n" + "\t\tdom_string_data(str),\n" + "\t\tdom_string_length(str));\n" + "\tdom_string_unref(str);\n" + "\n" + "\treturn 1;\n"); + break; + + case WEBIDL_TYPE_BOOL: + fprintf(outf, + "\tdom_exception exc;\n" + "\tbool b;\n" + "\n"); + fprintf(outf, + "\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, + "\tif (exc != DOM_NO_ERR) {\n" + "\t\treturn 0;\n" + "\t}\n" + "\n" + "\tduk_push_boolean(ctx, b);\n" + "\n" + "\treturn 1;\n"); + break; + + default: + return -1; + + } + + WARN(WARNING_GENERATED, + "Generated: getter %s::%s();", + interfacee->name, atributee->name); + + return 0; +} + +/** + * Output class property getter for a single attribute + */ +static int +output_attribute_getter(FILE* outf, struct ir_entry *interfacee, struct ir_attribute_entry *atributee) { - int cdatac; - - /* setter definition */ + /* getter definition */ fprintf(outf, - "static duk_ret_t %s_%s_%s_setter(duk_context *ctx)\n", + "static duk_ret_t %s_%s_%s_getter(duk_context *ctx)\n", DLPFX, interfacee->class_name, atributee->name); fprintf(outf,"{\n"); output_get_method_private(outf, interfacee->class_name); - cdatac = output_ccode(outf, atributee->setter); - if (cdatac == 0) { - WARN(WARNING_UNIMPLEMENTED, - "Unimplemented: setter %s::%s();", - interfacee->name, atributee->name); + /* if binding available for this attribute getter process it */ + if (atributee->getter != NULL) { + int res; + res = output_ccode(outf, atributee->getter); + if (res == 0) { + /* no code provided for this getter so generate */ + res = output_generated_attribute_getter(outf, + interfacee, + atributee); + } + if (res >= 0) { + fprintf(outf, "}\n\n"); + return res; + } + } - /* no implementation so generate default */ - fprintf(outf,"\treturn 0;\n"); + WARN(WARNING_UNIMPLEMENTED, + "Unimplemented: getter %s::%s();", + interfacee->name, atributee->name); + + if (options->dbglog) { + fprintf(outf, "\tLOG(\"Unimplemented\");\n" ); } - fprintf(outf, "}\n\n"); + /* no implementation so generate default */ + fprintf(outf, + "\treturn 0;\n" + "}\n\n"); + + return 0; +} + +/** + * Generate class property setter for a single attribute + */ +static int +output_generated_attribute_setter(FILE* outf, + struct ir_entry *interfacee, + struct ir_attribute_entry *atributee) +{ + switch (atributee->base_type) { + case WEBIDL_TYPE_STRING: + fprintf(outf, + "\tdom_exception exc;\n" + "\tdom_string *str;\n" + "\tduk_size_t slen;\n" + "\tconst char *s;\n" + "\ts = duk_safe_to_lstring(ctx, 0, &slen);\n" + "\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, + "\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, + "\tdom_string_unref(str);\n" + "\tif (exc != DOM_NO_ERR) {\n" + "\t\treturn 0;\n" + "\t}\n" + "\n" + "\treturn 0;\n"); + break; + + case WEBIDL_TYPE_BOOL: + fprintf(outf, + "\tdom_exception exc;\n" + "\tbool b;\n" + "\n" + "\tb = duk_get_boolean(ctx, 0);\n" + "\n"); + fprintf(outf, + "\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, + "\tif (exc != DOM_NO_ERR) {\n" + "\t\treturn 0;\n" + "\t}\n" + "\n" + "\treturn 0;\n"); + break; + + default: + return -1; + + } + + WARN(WARNING_GENERATED, + "Generated: getter %s::%s();", + interfacee->name, atributee->name); return 0; } @@ -1233,18 +1380,8 @@ output_putforwards_setter(FILE* outf, struct ir_entry *interfacee, struct ir_attribute_entry *atributee) { - /* use explicit implementation in bindings if present */ - if (atributee->setter != NULL) { - return output_attribute_setter(outf, interfacee, atributee); - } - /* generate autogenerated putforwards */ - fprintf(outf, - "static duk_ret_t %s_%s_%s_setter(duk_context *ctx)\n", - DLPFX, interfacee->class_name, atributee->name); - fprintf(outf,"{\n"); - fprintf(outf,"\tduk_ret_t get_ret;\n\n"); fprintf(outf, @@ -1268,51 +1405,82 @@ output_putforwards_setter(FILE* outf, "\tduk_pop(ctx);\n\n" "\treturn 0;\n"); - fprintf(outf, "}\n\n"); - return 0; } /** - * Generate class property getter/setter for a single attribute + * Generate class property setter for a single attribute */ static int -output_interface_attribute(FILE* outf, - struct ir_entry *interfacee, - struct ir_attribute_entry *atributee) +output_attribute_setter(FILE* outf, + struct ir_entry *interfacee, + struct ir_attribute_entry *atributee) { - int cdatac; - int res = 0; + int res = -1; - /* getter definition */ + /* setter definition */ fprintf(outf, - "static duk_ret_t %s_%s_%s_getter(duk_context *ctx)\n", + "static duk_ret_t %s_%s_%s_setter(duk_context *ctx)\n", DLPFX, interfacee->class_name, atributee->name); fprintf(outf,"{\n"); output_get_method_private(outf, interfacee->class_name); - cdatac = output_ccode(outf, atributee->getter); - if (cdatac == 0) { + /* if binding available for this attribute getter process it */ + if (atributee->setter != NULL) { + res = output_ccode(outf, atributee->setter); + if (res == 0) { + /* no code provided for this setter so generate */ + res = output_generated_attribute_setter(outf, + interfacee, + atributee); + } + } else if (atributee->putforwards != NULL) { + res = output_putforwards_setter(outf, + interfacee, + atributee); + } + + /* implementation not generated from any other source */ + if (res < 0) { WARN(WARNING_UNIMPLEMENTED, - "Unimplemented: getter %s::%s();", + "Unimplemented: setter %s::%s();", interfacee->name, atributee->name); + if (options->dbglog) { + fprintf(outf, "\tLOG(\"Unimplemented\");\n" ); + } + /* no implementation so generate default */ - fprintf(outf,"\treturn 0;\n"); + fprintf(outf, "\treturn 0;\n"); } fprintf(outf, "}\n\n"); - if (atributee->putforwards != NULL) { - res = output_putforwards_setter(outf, interfacee, atributee); - } else { - /* readonly attributes have no setter */ - if (atributee->modifier != WEBIDL_TYPE_MODIFIER_READONLY) { - res = output_attribute_setter(outf, - interfacee, - atributee); - } + return res; +} + + +/** + * Generate class property getter/setter for a single attribute + */ +static int +output_interface_attribute(FILE* outf, + struct ir_entry *interfacee, + struct ir_attribute_entry *atributee) +{ + int res; + + if (atributee->property_name == NULL) { + atributee->property_name = gen_idl2c_name(atributee->name); + } + + res = output_attribute_getter(outf, 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); } return res; @@ -469,6 +469,7 @@ attribute_map_new(struct webidl_node *interface, WEBIDL_NODE_TYPE_ATTRIBUTE); while (at_node != NULL) { + enum webidl_type *base_type; enum webidl_type_modifier *modifier; cure->node = at_node; @@ -485,6 +486,21 @@ attribute_map_new(struct webidl_node *interface, GENBIND_METHOD_TYPE_GETTER, cure->name); + /* find attributes base type */ + base_type = (enum webidl_type *)webidl_node_getint( + webidl_node_find_type( + webidl_node_getnode( + webidl_node_find_type( + webidl_node_getnode(at_node), + NULL, + WEBIDL_NODE_TYPE_TYPE)), + NULL, + WEBIDL_NODE_TYPE_TYPE_BASE)); + if (base_type != NULL) { + cure->base_type = *base_type; + } + + /* check for readonly attributes */ modifier = (enum webidl_type_modifier *)webidl_node_getint( webidl_node_find_type( @@ -52,11 +52,18 @@ struct ir_attribute_entry { const char *name; /** attribute name */ struct webidl_node *node; /**< AST attribute node */ - enum webidl_type_modifier modifier; + enum webidl_type base_type; /* type of attribute */ + enum webidl_type_modifier modifier; /* type modifier */ const char *putforwards; struct genbind_node *getter; /**< getter from binding */ struct genbind_node *setter; /**< getter from binding */ + + char *property_name; /**< the attribute name converted to output + * appropriate value. e.g. generators targetting c + * might lowercase the name or add underscores + * instead of caps + */ }; /** map entry for constants on an interface */ @@ -101,8 +108,8 @@ enum ir_entry_type { /** top level entry info common to interfaces and dictionaries */ struct ir_entry { - const char *name; /** dictionary name */ - struct webidl_node *node; /**< AST dictionary node */ + const char *name; /** IDL name */ + struct webidl_node *node; /**< AST node */ const char *inherit_name; /**< Name of interface inhertited from */ struct genbind_node *class; /**< class from binding (if any) */ |