diff options
-rw-r--r-- | src/jsapi-libdom.c | 139 | ||||
-rw-r--r-- | src/webidl-ast.c | 31 | ||||
-rw-r--r-- | src/webidl-ast.h | 13 | ||||
-rw-r--r-- | src/webidl-parser.y | 29 |
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); } |