summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/duk-libdom-interface.c262
-rw-r--r--src/ir.c16
-rw-r--r--src/ir.h13
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;
diff --git a/src/ir.c b/src/ir.c
index 6dc2d2a..2260d4f 100644
--- a/src/ir.c
+++ b/src/ir.c
@@ -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(
diff --git a/src/ir.h b/src/ir.h
index ecedc95..12f1e79 100644
--- a/src/ir.h
+++ b/src/ir.h
@@ -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) */