summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/duk-libdom-common.c39
-rw-r--r--src/duk-libdom-interface.c62
-rw-r--r--src/duk-libdom.c21
-rw-r--r--src/duk-libdom.h15
-rw-r--r--src/nsgenbind-ast.c34
-rw-r--r--src/nsgenbind-ast.h26
-rw-r--r--src/nsgenbind-lexer.l23
-rw-r--r--src/nsgenbind-parser.y219
-rw-r--r--src/nsgenbind.c2
9 files changed, 229 insertions, 212 deletions
diff --git a/src/duk-libdom-common.c b/src/duk-libdom-common.c
index 9a0f660..a1298e9 100644
--- a/src/duk-libdom-common.c
+++ b/src/duk-libdom-common.c
@@ -76,3 +76,42 @@ int output_tool_prologue(FILE* outf)
return 0;
}
+
+
+/* exported interface documented in duk-libdom.h */
+int output_ctype(FILE *outf, struct genbind_node *node, bool identifier)
+{
+ const char *type_cdata = NULL;
+ struct genbind_node *typename_node;
+
+ typename_node = genbind_node_find_type(genbind_node_getnode(node),
+ NULL,
+ GENBIND_NODE_TYPE_NAME);
+ while (typename_node != NULL) {
+ type_cdata = genbind_node_gettext(typename_node);
+
+ fprintf(outf, "%s", type_cdata);
+
+ typename_node = genbind_node_find_type(
+ genbind_node_getnode(node),
+ typename_node,
+ GENBIND_NODE_TYPE_NAME);
+
+ /* separate all but the last entry with spaces */
+ if (typename_node != NULL) {
+ fputc(' ', outf);
+ }
+ }
+
+ if (identifier) {
+ if ((type_cdata != NULL) &&
+ (type_cdata[0] != '*') &&
+ (type_cdata[0] != ' ')) {
+ fputc(' ', outf);
+ }
+
+ output_cdata(outf, node, GENBIND_NODE_TYPE_IDENT);
+ }
+
+ return 0;
+}
diff --git a/src/duk-libdom-interface.c b/src/duk-libdom-interface.c
index ad40741..38e1277 100644
--- a/src/duk-libdom-interface.c
+++ b/src/duk-libdom-interface.c
@@ -328,6 +328,42 @@ output_interface_destructor(FILE* outf, struct ir_entry *interfacee)
}
/**
+ * Compare two nodes to check their c types match.
+ */
+static bool compare_ctypes(struct genbind_node *a, struct genbind_node *b)
+{
+ struct genbind_node *ta;
+ struct genbind_node *tb;
+
+ ta = genbind_node_find_type(genbind_node_getnode(a),
+ NULL, GENBIND_NODE_TYPE_NAME);
+ tb = genbind_node_find_type(genbind_node_getnode(b),
+ NULL, GENBIND_NODE_TYPE_NAME);
+
+ while ((ta != NULL) && (tb != NULL)) {
+ char *txt_a;
+ char *txt_b;
+
+ txt_a = genbind_node_gettext(ta);
+ txt_b = genbind_node_gettext(tb);
+
+ if (strcmp(txt_a, txt_b) != 0) {
+ return false; /* missmatch */
+ }
+
+ ta = genbind_node_find_type(genbind_node_getnode(a),
+ ta, GENBIND_NODE_TYPE_NAME);
+ tb = genbind_node_find_type(genbind_node_getnode(b),
+ tb, GENBIND_NODE_TYPE_NAME);
+ }
+ if (ta != tb) {
+ return false;
+ }
+
+ return true;
+}
+
+/**
* generate an initialisor call to parent interface
*/
static int
@@ -389,26 +425,14 @@ output_interface_inherit_init(FILE* outf,
param_name);
return -1;
} else {
- char *param_type;
- char *inh_param_type;
-
fprintf(outf, ", ");
/* cast the parameter if required */
- param_type = genbind_node_gettext(
- genbind_node_find_type(
- genbind_node_getnode(param_node),
- NULL,
- GENBIND_NODE_TYPE_TYPE));
-
- inh_param_type = genbind_node_gettext(
- genbind_node_find_type(
- genbind_node_getnode(inh_param_node),
- NULL,
- GENBIND_NODE_TYPE_TYPE));
-
- if (strcmp(param_type, inh_param_type) != 0) {
- fprintf(outf, "(%s)", inh_param_type);
+ if (compare_ctypes(param_node,
+ inh_param_node) == false) {
+ fputc('(', outf);
+ output_ctype(outf, inh_param_node, false);
+ fputc(')', outf);
}
/* output the parameter identifier */
@@ -449,8 +473,8 @@ output_interface_init_declaration(FILE* outf,
while (param_node != NULL) {
interfacee->class_init_argc++;
fprintf(outf, ", ");
- output_cdata(outf, param_node, GENBIND_NODE_TYPE_TYPE);
- output_cdata(outf, param_node, GENBIND_NODE_TYPE_IDENT);
+
+ output_ctype(outf, param_node, true);
param_node = genbind_node_find_type(
genbind_node_getnode(init_node),
diff --git a/src/duk-libdom.c b/src/duk-libdom.c
index 084a68f..ee7cc3b 100644
--- a/src/duk-libdom.c
+++ b/src/duk-libdom.c
@@ -228,25 +228,10 @@ output_private_header(struct ir *ir)
NULL,
GENBIND_NODE_TYPE_PRIVATE);
while (priv_node != NULL) {
- /* generate the private variable definition ensuring
- * the type is separated from the identifier with
- * either a * or space.
- */
- const char *type_cdata;
- char cdatae;
- type_cdata = genbind_node_gettext(
- genbind_node_find_type(
- genbind_node_getnode(priv_node),
- NULL,
- GENBIND_NODE_TYPE_TYPE));
-
- fprintf(privf, "\t%s", type_cdata);
- cdatae = type_cdata[strlen(type_cdata) - 1];
- if ((cdatae != '*') && (cdatae != ' ')) {
- fputc(' ', privf);
- }
+ fprintf(privf, "\t");
+
+ output_ctype(privf, priv_node, true);
- output_cdata(privf, priv_node, GENBIND_NODE_TYPE_IDENT);
fprintf(privf, ";\n");
priv_node = genbind_node_find_type(
diff --git a/src/duk-libdom.h b/src/duk-libdom.h
index 79b440e..3b07009 100644
--- a/src/duk-libdom.h
+++ b/src/duk-libdom.h
@@ -56,4 +56,19 @@ int output_tool_prologue(FILE* outf);
*/
int output_cdata(FILE* outf, struct genbind_node *node, enum genbind_node_type nodetype);
+/**
+ * output a C variable type
+ *
+ * Used to output c type and optionlly identifier declarations for parameters
+ * and structure entries.
+ * If the optional identifier is output it is ensured the type is separated
+ * from the identifier with either a * or space.
+ *
+ * \param outf The file handle to write output.
+ * \param node The node to generate content for.
+ * \param identifier If the indentifier should be output.
+ * \return 0 on success.
+ */
+int output_ctype(FILE *outf, struct genbind_node *node, bool identifier);
+
#endif
diff --git a/src/nsgenbind-ast.c b/src/nsgenbind-ast.c
index 4f0654a..6b39461 100644
--- a/src/nsgenbind-ast.c
+++ b/src/nsgenbind-ast.c
@@ -259,34 +259,6 @@ genbind_node_find_type_ident(struct genbind_node *node,
return found_node;
}
-/* exported interface documented in nsgenbind-ast.h */
-struct genbind_node *
-genbind_node_find_type_type(struct genbind_node *node,
- struct genbind_node *prev,
- enum genbind_node_type type,
- const char *ident)
-{
- struct genbind_node *found_node;
- struct genbind_node *ident_node;
-
- found_node = genbind_node_find_type(node, prev, type);
-
-
- while (found_node != NULL) {
- /* look for a type node */
- ident_node = genbind_node_find_type(genbind_node_getnode(found_node),
- NULL,
- GENBIND_NODE_TYPE_TYPE);
- if (ident_node != NULL) {
- if (strcmp(ident_node->r.text, ident) == 0)
- break;
- }
-
- /* look for next matching node */
- found_node = genbind_node_find_type(node, found_node, type);
- }
- return found_node;
-}
/* exported interface documented in nsgenbind-ast.h */
@@ -371,7 +343,7 @@ char *genbind_node_gettext(struct genbind_node *node)
case GENBIND_NODE_TYPE_EPILOGUE:
case GENBIND_NODE_TYPE_POSTFACE:
case GENBIND_NODE_TYPE_IDENT:
- case GENBIND_NODE_TYPE_TYPE:
+ case GENBIND_NODE_TYPE_NAME:
case GENBIND_NODE_TYPE_CDATA:
return node->r.text;
@@ -449,8 +421,8 @@ static const char *genbind_node_type_to_str(enum genbind_node_type type)
case GENBIND_NODE_TYPE_BINDING:
return "Binding";
- case GENBIND_NODE_TYPE_TYPE:
- return "Type";
+ case GENBIND_NODE_TYPE_NAME:
+ return "TypeName";
case GENBIND_NODE_TYPE_PRIVATE:
return "Private";
diff --git a/src/nsgenbind-ast.h b/src/nsgenbind-ast.h
index 2a384b2..282544e 100644
--- a/src/nsgenbind-ast.h
+++ b/src/nsgenbind-ast.h
@@ -12,7 +12,7 @@
enum genbind_node_type {
GENBIND_NODE_TYPE_ROOT = 0,
GENBIND_NODE_TYPE_IDENT, /**< generic identifier string */
- GENBIND_NODE_TYPE_TYPE, /**< generic type string */
+ GENBIND_NODE_TYPE_NAME, /**< generic type string */
GENBIND_NODE_TYPE_MODIFIER, /**< node modifier */
GENBIND_NODE_TYPE_CDATA, /**< verbatim block of character data */
GENBIND_NODE_TYPE_STRING, /**< text string */
@@ -152,30 +152,6 @@ genbind_node_find_type_ident(struct genbind_node *node,
/**
- * Returning node of the specified type with a GENBIND_NODE_TYPE_TYPE
- * subnode with matching text.
- *
- * This is a conveniance wrapper around nested calls to
- * genbind_node_find_type() which performs a depth first left hand
- * search returning nodes of the specified type and a child node of
- * GENBIND_NODE_TYPE_TYPE with matching text.
- *
- *
- * @param node The node to start the search from
- * @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.
- */
-struct genbind_node *
-genbind_node_find_type_type(struct genbind_node *node,
- struct genbind_node *prev,
- enum genbind_node_type nodetype,
- const char *type_text);
-
-
-/**
* Find a method node of a given method type
*
* \param node A node of type GENBIND_NODE_TYPE_CLASS to search for methods.
diff --git a/src/nsgenbind-lexer.l b/src/nsgenbind-lexer.l
index d092195..f32a948 100644
--- a/src/nsgenbind-lexer.l
+++ b/src/nsgenbind-lexer.l
@@ -93,50 +93,39 @@ dblcolon \:\:
/* binding terminals */
binding return TOK_BINDING;
-
webidl return TOK_WEBIDL;
-
preface return TOK_PREFACE;
-
prologue return TOK_PROLOGUE;
-
epilogue return TOK_EPILOGUE;
-
postface return TOK_POSTFACE;
/* class member terminals */
class return TOK_CLASS;
-
private return TOK_PRIVATE;
-
internal return TOK_INTERNAL;
-
flags return TOK_FLAGS;
-
type return TOK_TYPE;
-
unshared return TOK_UNSHARED;
-
shared return TOK_SHARED;
-
property return TOK_PROPERTY;
/* implementation terminals */
init return TOK_INIT;
-
fini return TOK_FINI;
-
method return TOK_METHOD;
-
getter return TOK_GETTER;
-
setter return TOK_SETTER;
-
prototype return TOK_PROTOTYPE;
+ /* c type terminals */
+
+struct return TOK_STRUCT;
+union return TOK_UNION;
+unsigned return TOK_UNSIGNED;
+
/* other terminals */
{dblcolon} return TOK_DBLCOLON;
diff --git a/src/nsgenbind-parser.y b/src/nsgenbind-parser.y
index 1462b39..b883833 100644
--- a/src/nsgenbind-parser.y
+++ b/src/nsgenbind-parser.y
@@ -27,9 +27,9 @@ static void nsgenbind_error(YYLTYPE *locp,
struct genbind_node **genbind_ast,
const char *str)
{
- locp = locp;
- genbind_ast = genbind_ast;
- errtxt = strdup(str);
+ locp = locp;
+ genbind_ast = genbind_ast;
+ errtxt = strdup(str);
}
static struct genbind_node *
@@ -104,9 +104,9 @@ add_method(struct genbind_node **genbind_ast,
%union
{
- char *text;
- struct genbind_node *node;
- long value;
+ char *text;
+ struct genbind_node *node;
+ long value;
}
%token TOK_BINDING
@@ -135,6 +135,10 @@ add_method(struct genbind_node **genbind_ast,
%token TOK_DBLCOLON
+%token TOK_STRUCT
+%token TOK_UNION
+%token TOK_UNSIGNED
+
%token <text> TOK_IDENTIFIER
%token <text> TOK_STRING_LITERAL
%token <text> TOK_CCODE_LITERAL
@@ -169,38 +173,36 @@ add_method(struct genbind_node **genbind_ast,
%type <node> Property
%type <node> ParameterList
-%type <node> TypeIdent
+%type <node> CTypeIdent
+%type <node> CType
+%type <node> CTypeSpecifier
%%
-Input
- :
+Input:
Statements
- {
- *genbind_ast = $1;
+ {
+ *genbind_ast = $1;
}
;
-
-Statements
- :
- Statement
+Statements:
+ Statement
|
- Statements Statement
+ Statements Statement
{
- $$ = *genbind_ast = genbind_node_prepend($2, $1);
+ $$ = *genbind_ast = genbind_node_prepend($2, $1);
}
- |
- error ';'
- {
- fprintf(stderr, "%d: %s\n", yylloc.first_line, errtxt);
- free(errtxt);
- YYABORT ;
+ |
+ error ';'
+ {
+ fprintf(stderr, "%d: %s\n", yylloc.first_line, errtxt);
+ free(errtxt);
+ YYABORT ;
}
;
-Statement
- :
+Statement:
Binding
|
Class
@@ -208,18 +210,17 @@ Statement
Method
;
-Binding
- :
- TOK_BINDING TOK_IDENTIFIER '{' BindingArgs '}'
+Binding:
+ TOK_BINDING TOK_IDENTIFIER '{' BindingArgs '}' ';'
{
- $$ = genbind_new_node(GENBIND_NODE_TYPE_BINDING,
- NULL,
- genbind_new_node(GENBIND_NODE_TYPE_TYPE, $4, $2));
+ $$ = genbind_new_node(GENBIND_NODE_TYPE_BINDING,
+ NULL,
+ genbind_new_node(GENBIND_NODE_TYPE_NAME,
+ $4, $2));
}
;
-BindingArgs
- :
+BindingArgs:
BindingArg
|
BindingArgs BindingArg
@@ -228,8 +229,7 @@ BindingArgs
}
;
-BindingArg
- :
+BindingArg:
WebIDL
|
Preface
@@ -241,71 +241,102 @@ BindingArg
Postface
;
- /* [3] a web IDL file specifier */
-WebIDL
- :
+ /* a web IDL file specifier */
+WebIDL:
TOK_WEBIDL TOK_STRING_LITERAL ';'
{
- $$ = genbind_new_node(GENBIND_NODE_TYPE_WEBIDL, NULL, $2);
+ $$ = genbind_new_node(GENBIND_NODE_TYPE_WEBIDL, NULL, $2);
}
;
+ /* parse a c type specifier. This probably also needs to cope with
+ * void, char, short, int, long, float, double, signed, enum
+ */
+CTypeSpecifier:
+ TOK_UNSIGNED TOK_IDENTIFIER
+ {
+ $$ = genbind_new_node(GENBIND_NODE_TYPE_NAME,
+ genbind_new_node(GENBIND_NODE_TYPE_NAME,
+ NULL,
+ strdup("unsigned")),
+ $2);
+ }
+ |
+ TOK_STRUCT TOK_IDENTIFIER
+ {
+ $$ = genbind_new_node(GENBIND_NODE_TYPE_NAME,
+ genbind_new_node(GENBIND_NODE_TYPE_NAME,
+ NULL,
+ strdup("struct")),
+ $2);
+ }
+ |
+ TOK_UNION TOK_IDENTIFIER
+ {
+ $$ = genbind_new_node(GENBIND_NODE_TYPE_NAME,
+ genbind_new_node(GENBIND_NODE_TYPE_NAME,
+ NULL,
+ strdup("union")),
+ $2);
+ }
+ |
+ TOK_IDENTIFIER
+ {
+ $$ = genbind_new_node(GENBIND_NODE_TYPE_NAME, NULL, $1);
+ }
+ ;
+
+CType:
+ CTypeSpecifier
+ |
+ CTypeSpecifier '*'
+ {
+ $$ = genbind_new_node(GENBIND_NODE_TYPE_NAME, $1, strdup("*"));
+ }
/* type and identifier of a variable */
-TypeIdent
- :
- TOK_STRING_LITERAL TOK_IDENTIFIER
+CTypeIdent:
+ CType TOK_IDENTIFIER
{
- $$ = genbind_new_node(GENBIND_NODE_TYPE_IDENT,
- genbind_new_node(GENBIND_NODE_TYPE_TYPE, NULL, $1), $2);
+ $$ = genbind_new_node(GENBIND_NODE_TYPE_IDENT, $1, $2);
}
|
- TOK_STRING_LITERAL TOK_IDENTIFIER TOK_DBLCOLON TOK_IDENTIFIER
+ CType TOK_IDENTIFIER TOK_DBLCOLON TOK_IDENTIFIER
{
- $$ = genbind_new_node(GENBIND_NODE_TYPE_IDENT,
- genbind_new_node(GENBIND_NODE_TYPE_IDENT,
- genbind_new_node(GENBIND_NODE_TYPE_TYPE,
- NULL,
- $1),
- $2),
- $4);
+ $$ = genbind_new_node(GENBIND_NODE_TYPE_IDENT,
+ genbind_new_node(GENBIND_NODE_TYPE_IDENT, $1, $2), $4);
}
;
-Preface
- :
+Preface:
TOK_PREFACE CBlock ';'
{
- $$ = genbind_new_node(GENBIND_NODE_TYPE_PREFACE, NULL, $2);
+ $$ = genbind_new_node(GENBIND_NODE_TYPE_PREFACE, NULL, $2);
}
;
-Prologue
- :
+Prologue:
TOK_PROLOGUE CBlock ';'
{
$$ = genbind_new_node(GENBIND_NODE_TYPE_PROLOGUE, NULL, $2);
}
;
-Epilogue
- :
+Epilogue:
TOK_EPILOGUE CBlock ';'
{
$$ = genbind_new_node(GENBIND_NODE_TYPE_EPILOGUE, NULL, $2);
}
;
-Postface
- :
+Postface:
TOK_POSTFACE CBlock ';'
{
$$ = genbind_new_node(GENBIND_NODE_TYPE_POSTFACE, NULL, $2);
}
;
-CBlock
- :
+CBlock:
TOK_CCODE_LITERAL
|
CBlock TOK_CCODE_LITERAL
@@ -314,8 +345,7 @@ CBlock
}
;
-MethodType
- :
+MethodType:
TOK_INIT
{
$$ = GENBIND_METHOD_TYPE_INIT;
@@ -347,14 +377,13 @@ MethodType
}
;
-ParameterList
- :
- TypeIdent
+ParameterList:
+ CTypeIdent
{
$$ = genbind_new_node(GENBIND_NODE_TYPE_PARAMETER, NULL, $1);
}
|
- ParameterList ',' TypeIdent
+ ParameterList ',' CTypeIdent
{
$$ = genbind_node_prepend($1,
genbind_new_node(
@@ -364,8 +393,7 @@ ParameterList
}
;
-MethodDeclarator
- :
+MethodDeclarator:
TOK_IDENTIFIER TOK_DBLCOLON TOK_IDENTIFIER '(' ParameterList ')'
{
$$ = genbind_new_node(GENBIND_NODE_TYPE_CLASS,
@@ -406,8 +434,7 @@ MethodDeclarator
}
;
-Method
- :
+Method:
MethodType MethodDeclarator CBlock
{
$$ = add_method(genbind_ast, $1, $2, $3);
@@ -419,17 +446,15 @@ Method
}
;
-Class
- :
- TOK_CLASS TOK_IDENTIFIER '{' ClassArgs '}'
+Class:
+ TOK_CLASS TOK_IDENTIFIER '{' ClassArgs '}' ';'
{
$$ = genbind_new_node(GENBIND_NODE_TYPE_CLASS, NULL,
genbind_new_node(GENBIND_NODE_TYPE_IDENT, $4, $2));
}
;
-ClassArgs
- :
+ClassArgs:
ClassArg
|
ClassArgs ClassArg
@@ -438,8 +463,7 @@ ClassArgs
}
;
-ClassArg
- :
+ClassArg:
Private
|
Internal
@@ -458,45 +482,40 @@ ClassArg
;
-Private
- :
- TOK_PRIVATE TypeIdent ';'
+Private:
+ TOK_PRIVATE CTypeIdent ';'
{
- $$ = genbind_new_node(GENBIND_NODE_TYPE_PRIVATE, NULL, $2);
+ $$ = genbind_new_node(GENBIND_NODE_TYPE_PRIVATE, NULL, $2);
}
;
-Internal
- :
- TOK_INTERNAL TypeIdent ';'
+Internal:
+ TOK_INTERNAL CTypeIdent ';'
{
- $$ = genbind_new_node(GENBIND_NODE_TYPE_INTERNAL, NULL, $2);
+ $$ = genbind_new_node(GENBIND_NODE_TYPE_INTERNAL, NULL, $2);
}
;
-ClassFlag
- :
+ClassFlag:
TOK_FLAGS ClassFlags ';'
{
- $$ = genbind_new_node(GENBIND_NODE_TYPE_FLAGS, NULL, $2);
+ $$ = genbind_new_node(GENBIND_NODE_TYPE_FLAGS, NULL, $2);
}
;
-ClassFlags
- :
+ClassFlags:
TOK_IDENTIFIER
{
- $$ = genbind_new_node(GENBIND_NODE_TYPE_IDENT, NULL, $1);
+ $$ = genbind_new_node(GENBIND_NODE_TYPE_IDENT, NULL, $1);
}
|
ClassFlags ',' TOK_IDENTIFIER
{
- $$ = genbind_new_node(GENBIND_NODE_TYPE_IDENT, $1, $3);
+ $$ = genbind_new_node(GENBIND_NODE_TYPE_IDENT, $1, $3);
}
;
-Property
- :
+Property:
TOK_PROPERTY Modifiers TOK_IDENTIFIER ';'
{
$$ = genbind_new_node(GENBIND_NODE_TYPE_PROPERTY, NULL,
@@ -508,8 +527,7 @@ Property
}
;
-Modifiers
- :
+Modifiers:
/* empty */
{
$$ = GENBIND_TYPE_NONE;
@@ -521,8 +539,7 @@ Modifiers
}
;
-Modifier
- :
+Modifier:
TOK_TYPE
{
$$ = GENBIND_TYPE_TYPE;
diff --git a/src/nsgenbind.c b/src/nsgenbind.c
index 135c5c0..09d4c29 100644
--- a/src/nsgenbind.c
+++ b/src/nsgenbind.c
@@ -168,7 +168,7 @@ static enum bindingtype_e genbind_get_type(struct genbind_node *node)
genbind_node_find_type(
genbind_node_getnode(binding_node),
NULL,
- GENBIND_NODE_TYPE_TYPE));
+ GENBIND_NODE_TYPE_NAME));
if (binding_type == NULL) {
fprintf(stderr, "Error: missing binding type\n");
return BINDINGTYPE_UNKNOWN;