summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorVincent Sanders <vince@kyllikki.org>2013-12-16 00:08:27 +0000
committerVincent Sanders <vince@kyllikki.org>2014-05-16 14:38:56 +0100
commitabec5defbb553588dce1c317b74570061705f6d0 (patch)
treea88c2e25cf45358355219a6f832d227cebeffe9e /src
parent5755930ae93b6305b40620fff0e90bc2e4c64b46 (diff)
downloadnsgenbind-abec5defbb553588dce1c317b74570061705f6d0.tar.gz
nsgenbind-abec5defbb553588dce1c317b74570061705f6d0.tar.bz2
add flags to interface within binding
Diffstat (limited to 'src')
-rw-r--r--src/jsapi-libdom-property.c15
-rw-r--r--src/jsapi-libdom.c71
-rw-r--r--src/nsgenbind-ast.c13
-rw-r--r--src/nsgenbind-ast.h33
-rw-r--r--src/nsgenbind-lexer.l2
-rw-r--r--src/nsgenbind-parser.y54
6 files changed, 152 insertions, 36 deletions
diff --git a/src/jsapi-libdom-property.c b/src/jsapi-libdom-property.c
index 2bd3068..091b2c6 100644
--- a/src/jsapi-libdom-property.c
+++ b/src/jsapi-libdom-property.c
@@ -229,6 +229,7 @@ get_binding_shared_modifier(struct binding *binding, const char *type, const cha
{
struct genbind_node *shared_node;
struct genbind_node *shared_mod_node;
+ enum genbind_type_modifier *shared_modifier;
/* look for node matching the ident first */
shared_node = genbind_node_find_type_ident(binding->binding_list,
@@ -251,9 +252,11 @@ get_binding_shared_modifier(struct binding *binding, const char *type, const cha
shared_mod_node = genbind_node_find_type(genbind_node_getnode(shared_node),
NULL,
GENBIND_NODE_TYPE_MODIFIER);
- if (shared_mod_node != NULL) {
- return genbind_node_getint(shared_mod_node);
+ shared_modifier = (enum genbind_type_modifier *)genbind_node_getint(shared_mod_node);
+ if (shared_modifier != NULL) {
+ return *shared_modifier;
}
+
}
return GENBIND_TYPE_NONE;
}
@@ -1108,14 +1111,16 @@ static int typehandler_property_cb(struct genbind_node *node, void *ctx)
struct genbind_node *ident_node;
const char *type;
struct genbind_node *mod_node;
- enum genbind_type_modifier share_mod;
+ enum genbind_type_modifier *share_mod;
int ret = 0;
mod_node = genbind_node_find_type(genbind_node_getnode(node),
NULL,
GENBIND_NODE_TYPE_MODIFIER);
- share_mod = genbind_node_getint(mod_node);
- if ((share_mod & GENBIND_TYPE_TYPE) == GENBIND_TYPE_TYPE) {
+ share_mod = (enum genbind_type_modifier *)genbind_node_getint(mod_node);
+
+ if ((share_mod != NULL) &&
+ ((*share_mod & GENBIND_TYPE_TYPE) == GENBIND_TYPE_TYPE)) {
/* type handler */
ident_node = genbind_node_find_type(genbind_node_getnode(node),
diff --git a/src/jsapi-libdom.c b/src/jsapi-libdom.c
index 97a6193..2389a57 100644
--- a/src/jsapi-libdom.c
+++ b/src/jsapi-libdom.c
@@ -211,6 +211,10 @@ output_epilogue(struct binding *binding)
static int
output_prologue(struct binding *binding)
{
+ /* forward declare property list */
+ fprintf(binding->outfile,
+ "static JSPropertySpec jsclass_properties[];\n\n");
+
genbind_node_for_each_type(binding->gb_ast,
GENBIND_NODE_TYPE_PROLOGUE,
webidl_prologue_cb,
@@ -728,7 +732,7 @@ output_class_new(struct binding *binding)
}
static int
-output_jsclass(struct binding *binding)
+output_forward_declarations(struct binding *binding)
{
/* forward declare add property */
if (binding->addproperty != NULL) {
@@ -778,10 +782,12 @@ output_jsclass(struct binding *binding)
"static void jsclass_finalize(JSContext *cx, JSObject *obj);\n\n");
}
- /* forward declare property list */
- fprintf(binding->outfile,
- "static JSPropertySpec jsclass_properties[];\n\n");
+ return 0;
+}
+static int
+output_jsclass(struct binding *binding)
+{
/* output the class declaration */
HDROUTF(binding, "JSClass JSClass_%s;\n", binding->interface);
@@ -860,31 +866,36 @@ output_jsclass(struct binding *binding)
/* resolver */
if (binding->resolve != NULL) {
- fprintf(binding->outfile, "\t(JSResolveOp)jsclass_resolve,\n");
+ fprintf(binding->outfile,
+ "\t(JSResolveOp)jsclass_resolve,\t/* resolve */\n");
} else {
- fprintf(binding->outfile, "\tJS_ResolveStub,\n");
+ fprintf(binding->outfile,
+ "\tJS_ResolveStub,\t\t/* resolve */\n");
}
- fprintf(binding->outfile, "\tJS_ConvertStub,\t/* convert */\n");
+ fprintf(binding->outfile, "\tJS_ConvertStub,\t\t/* convert */\n");
if (binding->has_private || (binding->finalise != NULL)) {
- fprintf(binding->outfile, "\tjsclass_finalize,\n");
+ fprintf(binding->outfile,
+ "\tjsclass_finalize,\t/* finalizer */\n");
} else {
- fprintf(binding->outfile, "\tJS_FinalizeStub,\n");
+ fprintf(binding->outfile,
+ "\tJS_FinalizeStub,\t/* finalizer */\n");
}
fprintf(binding->outfile,
- "\t0,\t/* reserved */\n"
- "\tNULL,\t/* checkAccess */\n"
- "\tNULL,\t/* call */\n"
- "\tNULL,\t/* construct */\n"
- "\tNULL,\t/* xdr Object */\n"
- "\tNULL,\t/* hasInstance */\n");
+ "\t0,\t\t\t/* reserved */\n"
+ "\tNULL,\t\t\t/* checkAccess */\n"
+ "\tNULL,\t\t\t/* call */\n"
+ "\tNULL,\t\t\t/* construct */\n"
+ "\tNULL,\t\t\t/* xdr Object */\n"
+ "\tNULL,\t\t\t/* hasInstance */\n");
/* trace/mark */
if (binding->mark != NULL) {
- fprintf(binding->outfile, "\tJSAPI_JSCLASS_MARKOP(jsclass_mark),\n");
+ fprintf(binding->outfile,
+ "\tJSAPI_JSCLASS_MARKOP(jsclass_mark),\n");
} else {
- fprintf(binding->outfile, "\tNULL, /* trace/mark */\n");
+ fprintf(binding->outfile, "\tNULL,\t\t\t/* trace/mark */\n");
}
fprintf(binding->outfile,
@@ -1011,6 +1022,7 @@ binding_has_private(struct genbind_node *binding_list)
return false;
}
+/* determine if the binding has a global api marker */
static bool
binding_has_global(struct binding *binding)
{
@@ -1034,6 +1046,7 @@ binding_new(struct options *options,
struct binding *nb;
struct genbind_node *interface_node;
struct genbind_node *binding_list;
+ struct genbind_node *binding_ident;
char *hdrguard = NULL;
struct webidl_node *webidl_ast = NULL;
int res;
@@ -1043,6 +1056,7 @@ binding_new(struct options *options,
return NULL;
}
+ /* find the first interface node - there must be at least one */
interface_node = genbind_node_find_type(binding_list,
NULL,
GENBIND_NODE_TYPE_BINDING_INTERFACE);
@@ -1050,7 +1064,18 @@ binding_new(struct options *options,
return NULL;
}
- /* walk ast and load any web IDL files required */
+ /* get the binding identifier */
+ /* @todo it should be possible to specify this as part of the
+ * binding instead of just using the first interface
+ */
+ binding_ident = genbind_node_find_type(genbind_node_getnode(interface_node),
+ NULL,
+ GENBIND_NODE_TYPE_IDENT);
+ if (binding_ident == NULL) {
+ return NULL;
+ }
+
+ /* walk AST and load any web IDL files required */
res = read_webidl(genbind_ast, &webidl_ast);
if (res != 0) {
fprintf(stderr, "Error reading Web IDL files\n");
@@ -1077,7 +1102,8 @@ binding_new(struct options *options,
nb->gb_ast = genbind_ast;
nb->wi_ast = webidl_ast;
- nb->interface = genbind_node_gettext(interface_node);
+ /* @todo binding name should not be called interface */
+ nb->interface = genbind_node_gettext(binding_ident);
nb->outfile = options->outfilehandle;
nb->srcfile = options->outfilehandle;
nb->hdrfile = options->hdrfilehandle;
@@ -1160,6 +1186,11 @@ jsapi_libdom_output(struct options *options,
return 70;
}
+ res = output_forward_declarations(binding);
+ if (res) {
+ return 75;
+ }
+
res = output_jsclass(binding);
if (res) {
return 80;
@@ -1170,7 +1201,7 @@ jsapi_libdom_output(struct options *options,
return 85;
}
- /* user code outout just before function bodies emitted */
+ /* user code output just before function bodies emitted */
res = output_prologue(binding);
if (res) {
return 89;
diff --git a/src/nsgenbind-ast.c b/src/nsgenbind-ast.c
index 851cbeb..d20975f 100644
--- a/src/nsgenbind-ast.c
+++ b/src/nsgenbind-ast.c
@@ -211,7 +211,6 @@ char *genbind_node_gettext(struct genbind_node *node)
case GENBIND_NODE_TYPE_EPILOGUE:
case GENBIND_NODE_TYPE_IDENT:
case GENBIND_NODE_TYPE_TYPE:
- case GENBIND_NODE_TYPE_BINDING_INTERFACE:
case GENBIND_NODE_TYPE_CBLOCK:
return node->r.text;
@@ -231,6 +230,8 @@ struct genbind_node *genbind_node_getnode(struct genbind_node *node)
case GENBIND_NODE_TYPE_BINDING_PRIVATE:
case GENBIND_NODE_TYPE_BINDING_INTERNAL:
case GENBIND_NODE_TYPE_BINDING_PROPERTY:
+ case GENBIND_NODE_TYPE_BINDING_INTERFACE:
+ case GENBIND_NODE_TYPE_BINDING_INTERFACE_FLAGS:
case GENBIND_NODE_TYPE_OPERATION:
case GENBIND_NODE_TYPE_API:
case GENBIND_NODE_TYPE_GETTER:
@@ -245,19 +246,18 @@ struct genbind_node *genbind_node_getnode(struct genbind_node *node)
}
-int genbind_node_getint(struct genbind_node *node)
+int *genbind_node_getint(struct genbind_node *node)
{
if (node != NULL) {
switch(node->type) {
case GENBIND_NODE_TYPE_MODIFIER:
- return node->r.number;
+ return &node->r.number;
default:
break;
}
}
- return -1;
-
+ return NULL;
}
static const char *genbind_node_type_to_str(enum genbind_node_type type)
@@ -296,6 +296,9 @@ static const char *genbind_node_type_to_str(enum genbind_node_type type)
case GENBIND_NODE_TYPE_BINDING_INTERFACE:
return "Interface";
+ case GENBIND_NODE_TYPE_BINDING_INTERFACE_FLAGS:
+ return "Flags";
+
case GENBIND_NODE_TYPE_BINDING_PROPERTY:
return "Property";
diff --git a/src/nsgenbind-ast.h b/src/nsgenbind-ast.h
index 6513f7f..d59aeba 100644
--- a/src/nsgenbind-ast.h
+++ b/src/nsgenbind-ast.h
@@ -26,6 +26,7 @@ enum genbind_node_type {
GENBIND_NODE_TYPE_BINDING_PRIVATE,
GENBIND_NODE_TYPE_BINDING_INTERNAL,
GENBIND_NODE_TYPE_BINDING_INTERFACE,
+ GENBIND_NODE_TYPE_BINDING_INTERFACE_FLAGS,
GENBIND_NODE_TYPE_BINDING_PROPERTY,
GENBIND_NODE_TYPE_API,
GENBIND_NODE_TYPE_OPERATION,
@@ -41,6 +42,11 @@ enum genbind_type_modifier {
GENBIND_TYPE_TYPE_UNSHARED = 3, /**< identifies a unshared type handler */
};
+/* interface flags */
+enum genbind_interface_flags {
+ GENBIND_INTERFACE_FLAG_NONE = 0,
+ GENBIND_INTERFACE_FLAG_GLOBAL = 1, /**< interface is global */
+};
struct genbind_node;
@@ -111,8 +117,8 @@ genbind_node_find_type_ident(struct genbind_node *node,
* @param prev The node at which to stop the search, either NULL to
* search the full tree depth (initial search) or the result
* of a previous search to continue.
- * @param nodetype The type of node to seach for
- * @param type The text to match the type child node to
+ * @param nodetype The type of node to seach for.
+ * @param type The text to match the type child node to.
*/
struct genbind_node *
genbind_node_find_type_type(struct genbind_node *node,
@@ -122,9 +128,28 @@ genbind_node_find_type_type(struct genbind_node *node,
int genbind_node_for_each_type(struct genbind_node *node, enum genbind_node_type type, genbind_callback_t *cb, void *ctx);
-char *genbind_node_gettext(struct genbind_node *node);
+/** get a nodes node list content
+ *
+ * @param node The nodes to get node list from
+ * @return pointer to the node list or NULL if the node does not contain a list
+ */
struct genbind_node *genbind_node_getnode(struct genbind_node *node);
-int genbind_node_getint(struct genbind_node *node);
+
+/** get a nodes text content
+ *
+ * @param node The nodes to get text from
+ * @return pointer to the node text or NULL if the node is not of type
+ * text or is empty.
+ */
+char *genbind_node_gettext(struct genbind_node *node);
+
+/** get a nodes integer value
+ *
+ * @param node The nodes to get integer from
+ * @return pointer to the node value or NULL if the node is not of type
+ * int or is empty.
+ */
+int *genbind_node_getint(struct genbind_node *node);
#ifdef _WIN32
#define NEED_STRNDUP 1
diff --git a/src/nsgenbind-lexer.l b/src/nsgenbind-lexer.l
index 8189a72..4b5e225 100644
--- a/src/nsgenbind-lexer.l
+++ b/src/nsgenbind-lexer.l
@@ -104,6 +104,8 @@ binding return TOK_BINDING;
interface return TOK_INTERFACE;
+flags return TOK_FLAGS;
+
type return TOK_TYPE;
private return TOK_PRIVATE;
diff --git a/src/nsgenbind-parser.y b/src/nsgenbind-parser.y
index b9ec23b..b37ab9d 100644
--- a/src/nsgenbind-parser.y
+++ b/src/nsgenbind-parser.y
@@ -54,6 +54,7 @@ char *errtxt;
%token TOK_GETTER
%token TOK_SETTER
%token TOK_INTERFACE
+%token TOK_FLAGS
%token TOK_TYPE
%token TOK_PRIVATE
%token TOK_INTERNAL
@@ -84,6 +85,9 @@ char *errtxt;
%type <node> Private
%type <node> Internal
%type <node> Interface
+%type <node> InterfaceArgs
+%type <node> InterfaceArg
+%type <node> InterfaceFlags
%type <node> Property
%type <node> Operation
%type <node> Api
@@ -91,6 +95,7 @@ char *errtxt;
%type <node> Setter
+
%%
Input
@@ -260,7 +265,7 @@ Setter
Binding
:
- TOK_BINDING TOK_IDENTIFIER '{' BindingArgs '}'
+ TOK_BINDING TOK_IDENTIFIER '{' BindingArgs '}'
{
$$ = genbind_new_node(GENBIND_NODE_TYPE_BINDING,
NULL,
@@ -313,7 +318,52 @@ Interface
:
TOK_INTERFACE TOK_IDENTIFIER ';'
{
- $$ = genbind_new_node(GENBIND_NODE_TYPE_BINDING_INTERFACE, NULL, $2);
+ $$ = genbind_new_node(GENBIND_NODE_TYPE_BINDING_INTERFACE, NULL,
+ genbind_new_node(GENBIND_NODE_TYPE_IDENT, NULL, $2));
+ }
+ |
+ TOK_INTERFACE TOK_IDENTIFIER '{' '}'
+ {
+ $$ = genbind_new_node(GENBIND_NODE_TYPE_BINDING_INTERFACE, NULL,
+ genbind_new_node(GENBIND_NODE_TYPE_IDENT, NULL, $2));
+ }
+ |
+ TOK_INTERFACE TOK_IDENTIFIER '{' InterfaceArgs '}'
+ {
+ $$ = genbind_new_node(GENBIND_NODE_TYPE_BINDING_INTERFACE,
+ NULL,
+ genbind_new_node(GENBIND_NODE_TYPE_IDENT, $4, $2));
+ }
+ ;
+
+InterfaceArgs
+ :
+ InterfaceArg
+ |
+ InterfaceArgs InterfaceArg
+ {
+ $$ = genbind_node_link($2, $1);
+ }
+ ;
+
+InterfaceArg
+ :
+ TOK_FLAGS InterfaceFlags ';'
+ {
+ $$ = genbind_new_node(GENBIND_NODE_TYPE_BINDING_INTERFACE_FLAGS, NULL, $2);
+ }
+ ;
+
+InterfaceFlags
+ :
+ TOK_IDENTIFIER
+ {
+ $$ = genbind_new_node(GENBIND_NODE_TYPE_IDENT, NULL, $1);
+ }
+ |
+ InterfaceFlags ',' TOK_IDENTIFIER
+ {
+ $$ = genbind_new_node(GENBIND_NODE_TYPE_IDENT, $1, $3);
}
;