summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorVincent Sanders <vincent.sanders@collabora.co.uk>2012-09-26 18:54:34 +0100
committerVincent Sanders <vincent.sanders@collabora.co.uk>2012-09-26 18:54:34 +0100
commitcaf565eb318cdf19a1d5e4b4bab7cd462301efef (patch)
treea2d1757530af5d385b07e4d77ab2d8745cdf88c5 /src
parent74ea37fbd83a0d381ae928c7f7e30d0ded875cc0 (diff)
downloadnsgenbind-caf565eb318cdf19a1d5e4b4bab7cd462301efef.tar.gz
nsgenbind-caf565eb318cdf19a1d5e4b4bab7cd462301efef.tar.bz2
add modifier to allow setting of readonly or unsigned etc.
add property getter/setter body
Diffstat (limited to 'src')
-rw-r--r--src/jsapi-libdom.c139
-rw-r--r--src/webidl-ast.c31
-rw-r--r--src/webidl-ast.h13
-rw-r--r--src/webidl-parser.y29
4 files changed, 202 insertions, 10 deletions
diff --git a/src/jsapi-libdom.c b/src/jsapi-libdom.c
index 00b56a9..8a30854 100644
--- a/src/jsapi-libdom.c
+++ b/src/jsapi-libdom.c
@@ -109,21 +109,33 @@ static int webidl_property_spec_cb(struct webidl_node *node, void *ctx)
{
FILE *outfile = ctx;
struct webidl_node *ident_node;
+ struct webidl_node *modifier_node;
ident_node = webidl_node_find(webidl_node_getnode(node),
NULL,
webidl_cmp_node_type,
(void *)WEBIDL_NODE_TYPE_IDENT);
+ modifier_node = webidl_node_find(webidl_node_getnode(node),
+ NULL,
+ webidl_cmp_node_type,
+ (void *)WEBIDL_NODE_TYPE_MODIFIER);
+
if (ident_node == NULL) {
/* properties must have an operator
* http://www.w3.org/TR/WebIDL/#idl-attributes
*/
return 1;
} else {
+ if (webidl_node_getint(modifier_node) == WEBIDL_TYPE_READONLY) {
+ fprintf(outfile,
+ " JSAPI_PS_RO(%s, 0, JSPROP_ENUMERATE | JSPROP_SHARED),\n",
+ webidl_node_gettext(ident_node));
+ } else {
fprintf(outfile,
" JSAPI_PS(%s, 0, JSPROP_ENUMERATE | JSPROP_SHARED),\n",
webidl_node_gettext(ident_node));
+ }
}
return 0;
}
@@ -397,6 +409,125 @@ output_function_body(FILE *outfile,
}
+static int webidl_property_body_cb(struct webidl_node *node, void *ctx)
+{
+ FILE *outfile = ctx;
+ struct webidl_node *ident_node;
+ struct webidl_node *modifier_node;
+
+ ident_node = webidl_node_find(webidl_node_getnode(node),
+ NULL,
+ webidl_cmp_node_type,
+ (void *)WEBIDL_NODE_TYPE_IDENT);
+
+ if (ident_node == NULL) {
+ /* properties must have an operator
+ * http://www.w3.org/TR/WebIDL/#idl-attributes
+ */
+ return 1;
+ }
+
+ modifier_node = webidl_node_find(webidl_node_getnode(node),
+ NULL,
+ webidl_cmp_node_type,
+ (void *)WEBIDL_NODE_TYPE_MODIFIER);
+
+
+ if (webidl_node_getint(modifier_node) != WEBIDL_TYPE_READONLY) {
+ /* no readonly so a set function is required */
+
+ fprintf(outfile,
+ "static JSBool JSAPI_PROPERTYSET(%s, JSContext *cx, JSObject *obj, jsval *vp)\n",
+ webidl_node_gettext(ident_node));
+ fprintf(outfile,
+ "{\n"
+ " return JS_FALSE;\n"
+ "}\n\n");
+ }
+
+ fprintf(outfile,
+ "static JSBool JSAPI_PROPERTYGET(%s, JSContext *cx, JSObject *obj, jsval *vp)\n",
+ webidl_node_gettext(ident_node));
+ fprintf(outfile,
+ "{\n"
+ " JS_SET_RVAL(cx, vp, JSVAL_NULL);\n"
+ " return JS_TRUE;\n");
+ fprintf(outfile, "}\n\n");
+
+
+ return 0;
+}
+
+static int
+generate_property_body(FILE *outfile,
+ const char *interface,
+ struct webidl_node *webidl_ast)
+{
+ struct webidl_node *interface_node;
+ struct webidl_node *members_node;
+ struct webidl_node *inherit_node;
+
+
+ /* find interface in webidl with correct ident attached */
+ interface_node = webidl_node_find_type_ident(webidl_ast,
+ WEBIDL_NODE_TYPE_INTERFACE,
+ interface);
+
+ if (interface_node == NULL) {
+ fprintf(stderr,
+ "Unable to find interface %s in loaded WebIDL\n",
+ interface);
+ return -1;
+ }
+
+ members_node = webidl_node_find(webidl_node_getnode(interface_node),
+ NULL,
+ webidl_cmp_node_type,
+ (void *)WEBIDL_NODE_TYPE_LIST);
+
+ while (members_node != NULL) {
+
+ fprintf(outfile,"/**** %s ****/\n", interface);
+
+ /* for each function emit property body */
+ webidl_node_for_each_type(webidl_node_getnode(members_node),
+ WEBIDL_NODE_TYPE_ATTRIBUTE,
+ webidl_property_body_cb,
+ outfile);
+
+
+ members_node = webidl_node_find(webidl_node_getnode(interface_node),
+ members_node,
+ webidl_cmp_node_type,
+ (void *)WEBIDL_NODE_TYPE_LIST);
+
+ }
+ /* check for inherited nodes and insert them too */
+ inherit_node = webidl_node_find(webidl_node_getnode(interface_node),
+ NULL,
+ webidl_cmp_node_type,
+ (void *)WEBIDL_NODE_TYPE_INTERFACE_INHERITANCE);
+
+ if (inherit_node != NULL) {
+ return generate_property_body(outfile,
+ webidl_node_gettext(inherit_node),
+ webidl_ast);
+ }
+
+ return 0;
+}
+
+static int
+output_property_body(FILE *outfile,
+ struct binding *binding,
+ struct webidl_node *webidl_ast)
+{
+ int res;
+
+ res = generate_property_body(outfile, binding->interface, webidl_ast);
+
+ return res;
+}
static struct binding *binding_new(struct genbind_node *genbind_ast)
{
@@ -480,15 +611,19 @@ int jsapi_libdom_output(char *outfilename, struct genbind_node *genbind_ast)
return 5;
}
+ res = output_property_body(outfile, binding, webidl_ast);
+ if (res) {
+ return 6;
+ }
res = output_function_spec(outfile, binding, webidl_ast);
if (res) {
- return 5;
+ return 7;
}
res = output_property_spec(outfile, binding, webidl_ast);
if (res) {
- return 5;
+ return 8;
}
fclose(outfile);
diff --git a/src/webidl-ast.c b/src/webidl-ast.c
index a5f2d23..8160d55 100644
--- a/src/webidl-ast.c
+++ b/src/webidl-ast.c
@@ -189,6 +189,22 @@ char *webidl_node_gettext(struct webidl_node *node)
}
}
+int
+webidl_node_getint(struct webidl_node *node)
+{
+ if (node != NULL) {
+ switch(node->type) {
+ case WEBIDL_NODE_TYPE_MODIFIER:
+ case WEBIDL_NODE_TYPE_TYPE_BASE:
+ return node->r.number;
+
+ default:
+ break;
+ }
+ }
+ return -1;
+
+}
struct webidl_node *webidl_node_getnode(struct webidl_node *node)
{
if (node != NULL) {
@@ -249,7 +265,7 @@ static const char *webidl_node_type_to_str(enum webidl_node_type type)
case WEBIDL_NODE_TYPE_TYPE_BASE:
return "Base";
- case WEBIDL_NODE_TYPE_TYPE_MODIFIER:
+ case WEBIDL_NODE_TYPE_MODIFIER:
return "Modifier";
default:
@@ -267,8 +283,17 @@ int webidl_ast_dump(struct webidl_node *node, int indent)
txt = webidl_node_gettext(node);
if (txt == NULL) {
- printf("\n");
- webidl_ast_dump(webidl_node_getnode(node), indent + 2);
+ struct webidl_node *next;
+
+ next = webidl_node_getnode(node);
+
+ if (next != NULL) {
+ printf("\n");
+ webidl_ast_dump(next, indent + 2);
+ } else {
+ /* not txt or node has to be an int */
+ printf(": %d\n", webidl_node_getint(node));
+ }
} else {
printf(": \"%s\"\n", txt);
}
diff --git a/src/webidl-ast.h b/src/webidl-ast.h
index ac3586f..7f21df5 100644
--- a/src/webidl-ast.h
+++ b/src/webidl-ast.h
@@ -10,10 +10,16 @@
#define genjsbind_webidl_ast_h
enum webidl_node_type {
+ /* generic node types which define structure or attributes */
WEBIDL_NODE_TYPE_ROOT = 0,
WEBIDL_NODE_TYPE_IDENT,
+ /** access modifier e.g. for attributes or types */
+ WEBIDL_NODE_TYPE_MODIFIER,
+ /** a list of nodes (interface members, arguments) */
+ WEBIDL_NODE_TYPE_LIST,
+
+ /* non structural node types */
WEBIDL_NODE_TYPE_INTERFACE,
- WEBIDL_NODE_TYPE_LIST, /* a list of nodes (interface members, arguments) */
WEBIDL_NODE_TYPE_INTERFACE_INHERITANCE,
WEBIDL_NODE_TYPE_ATTRIBUTE,
WEBIDL_NODE_TYPE_OPERATION,
@@ -22,10 +28,10 @@ enum webidl_node_type {
WEBIDL_NODE_TYPE_ELLIPSIS,
WEBIDL_NODE_TYPE_TYPE,
WEBIDL_NODE_TYPE_TYPE_BASE,
- WEBIDL_NODE_TYPE_TYPE_MODIFIER,
};
enum webidl_type {
+ WEBIDL_TYPE_USER,
WEBIDL_TYPE_BOOL,
WEBIDL_TYPE_BYTE,
WEBIDL_TYPE_OCTET,
@@ -38,13 +44,13 @@ enum webidl_type {
WEBIDL_TYPE_SEQUENCE,
WEBIDL_TYPE_OBJECT,
WEBIDL_TYPE_DATE,
- WEBIDL_TYPE_USER,
WEBIDL_TYPE_VOID,
};
enum webidl_type_modifier {
WEBIDL_TYPE_MODIFIER_UNSIGNED,
WEBIDL_TYPE_MODIFIER_UNRESTRICTED,
+ WEBIDL_TYPE_READONLY,
};
struct webidl_node;
@@ -66,6 +72,7 @@ struct webidl_node *webidl_add_interface_member(struct webidl_node *list, struct
/* node contents acessors */
char *webidl_node_gettext(struct webidl_node *node);
struct webidl_node *webidl_node_getnode(struct webidl_node *node);
+int webidl_node_getint(struct webidl_node *node);
/* node searches */
diff --git a/src/webidl-parser.y b/src/webidl-parser.y
index fef57dd..81f0dfc 100644
--- a/src/webidl-parser.y
+++ b/src/webidl-parser.y
@@ -161,7 +161,9 @@ webidl_error(YYLTYPE *locp, struct webidl_node **winbind_ast, const char *str)
%type <node> UnsignedIntegerType
%type <node> IntegerType
+%type <isit> ReadOnly
%type <isit> OptionalLong
+%type <isit> Inherit
%%
@@ -522,23 +524,46 @@ Attribute:
Inherit ReadOnly TOK_ATTRIBUTE Type TOK_IDENTIFIER ';'
{
struct webidl_node *attribute;
+
attribute = webidl_node_new(WEBIDL_NODE_TYPE_IDENT, NULL, $5);
+
+ /* add attributes type */
+ attribute = webidl_node_prepend(attribute, $4);
+
+ /* deal with readonly modifier */
+ if ($2) {
+ attribute = webidl_node_new(WEBIDL_NODE_TYPE_MODIFIER, attribute, (void *)WEBIDL_TYPE_READONLY);
+ }
+
$$ = webidl_node_new(WEBIDL_NODE_TYPE_ATTRIBUTE, NULL, attribute);
+
}
;
/* [33] */
Inherit:
/* empty */
+ {
+ $$ = false;
+ }
|
TOK_INHERIT
+ {
+ $$ = true;
+ }
;
/* [34] */
ReadOnly:
/* empty */
+ {
+ $$ = false;
+ }
|
TOK_READONLY
+ {
+ $$ = true;
+ }
;
/* [35] */
@@ -1036,7 +1061,7 @@ PrimitiveType:
UnrestrictedFloatType:
TOK_UNRESTRICTED FloatType
{
- $$ = webidl_node_new(WEBIDL_NODE_TYPE_TYPE_MODIFIER,
+ $$ = webidl_node_new(WEBIDL_NODE_TYPE_MODIFIER,
$2,
(void *)WEBIDL_TYPE_MODIFIER_UNRESTRICTED);
}
@@ -1061,7 +1086,7 @@ FloatType:
UnsignedIntegerType:
TOK_UNSIGNED IntegerType
{
- $$ = webidl_node_new(WEBIDL_NODE_TYPE_TYPE_MODIFIER,
+ $$ = webidl_node_new(WEBIDL_NODE_TYPE_MODIFIER,
$2,
(void *)WEBIDL_TYPE_MODIFIER_UNSIGNED);
}