summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Sanders <vince@kyllikki.org>2015-09-28 07:59:50 +0100
committerVincent Sanders <vince@kyllikki.org>2015-09-28 07:59:50 +0100
commitc80955dcc6b663c250a1f2552b626770fbd46a94 (patch)
tree4b6b98eb03095cbc722b7f5bc2e0bbfa9568e8b3
parent767e69459ca7b4c13fe93875177040ab3eec8b56 (diff)
downloadnsgenbind-c80955dcc6b663c250a1f2552b626770fbd46a94.tar.gz
nsgenbind-c80955dcc6b663c250a1f2552b626770fbd46a94.tar.bz2
annotates binding AST with source linenumber and file
Uses annotated AST to put line directives in the generated source so any code errors in the binding can be easily located.
-rw-r--r--src/duk-libdom-common.c23
-rw-r--r--src/duk-libdom-interface.c14
-rw-r--r--src/duk-libdom.h13
-rw-r--r--src/nsgenbind-ast.c8
-rw-r--r--src/nsgenbind-ast.h3
-rw-r--r--src/nsgenbind-parser.y18
6 files changed, 65 insertions, 14 deletions
diff --git a/src/duk-libdom-common.c b/src/duk-libdom-common.c
index fc62863..fb97fe3 100644
--- a/src/duk-libdom-common.c
+++ b/src/duk-libdom-common.c
@@ -58,6 +58,29 @@ int output_cdata(FILE* outf,
}
/* exported interface documented in duk-libdom.h */
+int output_ccode(FILE* outf, struct genbind_node *node)
+{
+ int *line;
+ char *filename;
+
+ line = genbind_node_getint(
+ genbind_node_find_type(
+ genbind_node_getnode(node),
+ NULL, GENBIND_NODE_TYPE_LINE));
+
+ filename = genbind_node_gettext(
+ genbind_node_find_type(
+ genbind_node_getnode(node),
+ NULL, GENBIND_NODE_TYPE_FILE));
+
+ if ((line != NULL) && (filename != NULL)) {
+ fprintf(outf, "#line %d \"%s\"\n", *line, filename);
+ }
+
+ return output_cdata(outf, node, GENBIND_NODE_TYPE_CDATA);
+}
+
+/* exported interface documented in duk-libdom.h */
int output_tool_prologue(FILE* outf)
{
char *fpath;
diff --git a/src/duk-libdom-interface.c b/src/duk-libdom-interface.c
index 997cb9a..0fef35b 100644
--- a/src/duk-libdom-interface.c
+++ b/src/duk-libdom-interface.c
@@ -517,7 +517,7 @@ output_interface_init(FILE* outf,
}
/* output the initaliser code from the binding */
- output_cdata(outf, init_node, GENBIND_NODE_TYPE_CDATA);
+ output_ccode(outf, init_node);
fprintf(outf, "}\n\n");
@@ -1157,10 +1157,7 @@ output_interface_operation(FILE* outf,
output_get_method_private(outf, interfacee->class_name);
- cdatac = output_cdata(outf,
- operatione->method,
- GENBIND_NODE_TYPE_CDATA);
-
+ cdatac = output_ccode(outf, operatione->method);
if (cdatac == 0) {
/* no implementation so generate default */
WARN(WARNING_UNIMPLEMENTED,
@@ -1214,8 +1211,7 @@ output_interface_attribute(FILE* outf,
output_get_method_private(outf, interfacee->class_name);
- cdatac = output_cdata(outf, atributee->getter, GENBIND_NODE_TYPE_CDATA);
-
+ cdatac = output_ccode(outf, atributee->getter);
if (cdatac == 0) {
WARN(WARNING_UNIMPLEMENTED,
"Unimplemented: getter %s::%s();",
@@ -1240,8 +1236,7 @@ output_interface_attribute(FILE* outf,
output_get_method_private(outf, interfacee->class_name);
- cdatac = output_cdata(outf, atributee->setter, GENBIND_NODE_TYPE_CDATA);
-
+ cdatac = output_ccode(outf, atributee->setter);
if (cdatac == 0) {
WARN(WARNING_UNIMPLEMENTED,
"Unimplemented: setter %s::%s();",
@@ -1251,7 +1246,6 @@ output_interface_attribute(FILE* outf,
fprintf(outf,"\treturn 0;\n");
}
-
fprintf(outf, "}\n\n");
return 0;
diff --git a/src/duk-libdom.h b/src/duk-libdom.h
index b9eeea3..dd27420 100644
--- a/src/duk-libdom.h
+++ b/src/duk-libdom.h
@@ -56,6 +56,19 @@ int output_tool_prologue(FILE* outf);
*/
int output_cdata(FILE* outf, struct genbind_node *node, enum genbind_node_type nodetype);
+
+/**
+ * output c code with line directives if possible.
+ *
+ * used for any cdata sections
+ *
+ * \param outf The file handle to write output.
+ * \param node The node to search.
+ * \param nodetype the type of child node to search for.
+ * \return The number of nodes written or 0 for none.
+ */
+int output_ccode(FILE* outf, struct genbind_node *node);
+
/**
* output character data of method node of given type.
*
diff --git a/src/nsgenbind-ast.c b/src/nsgenbind-ast.c
index 749d3e8..9be8bc7 100644
--- a/src/nsgenbind-ast.c
+++ b/src/nsgenbind-ast.c
@@ -341,6 +341,7 @@ char *genbind_node_gettext(struct genbind_node *node)
case GENBIND_NODE_TYPE_IDENT:
case GENBIND_NODE_TYPE_NAME:
case GENBIND_NODE_TYPE_CDATA:
+ case GENBIND_NODE_TYPE_FILE:
return node->r.text;
default:
@@ -377,6 +378,7 @@ int *genbind_node_getint(struct genbind_node *node)
if (node != NULL) {
switch(node->type) {
case GENBIND_NODE_TYPE_METHOD_TYPE:
+ case GENBIND_NODE_TYPE_LINE:
case GENBIND_NODE_TYPE_MODIFIER:
return &node->r.number;
@@ -408,6 +410,12 @@ static const char *genbind_node_type_to_str(enum genbind_node_type type)
case GENBIND_NODE_TYPE_NAME:
return "TypeName";
+ case GENBIND_NODE_TYPE_LINE:
+ return "Linenumber";
+
+ case GENBIND_NODE_TYPE_FILE:
+ return "Filename";
+
case GENBIND_NODE_TYPE_PRIVATE:
return "Private";
diff --git a/src/nsgenbind-ast.h b/src/nsgenbind-ast.h
index b130db2..49db23b 100644
--- a/src/nsgenbind-ast.h
+++ b/src/nsgenbind-ast.h
@@ -16,6 +16,8 @@ enum genbind_node_type {
GENBIND_NODE_TYPE_MODIFIER, /**< node modifier */
GENBIND_NODE_TYPE_CDATA, /**< verbatim block of character data */
GENBIND_NODE_TYPE_STRING, /**< text string */
+ GENBIND_NODE_TYPE_LINE, /**< linenumber */
+ GENBIND_NODE_TYPE_FILE, /**< file name */
GENBIND_NODE_TYPE_BINDING, /**< Binding */
GENBIND_NODE_TYPE_WEBIDL,
@@ -28,6 +30,7 @@ enum genbind_node_type {
GENBIND_NODE_TYPE_METHOD, /**< binding method */
GENBIND_NODE_TYPE_METHOD_TYPE, /**< binding method type */
+
GENBIND_NODE_TYPE_PARAMETER, /**< method parameter */
};
diff --git a/src/nsgenbind-parser.y b/src/nsgenbind-parser.y
index b52d0d0..a3e5609 100644
--- a/src/nsgenbind-parser.y
+++ b/src/nsgenbind-parser.y
@@ -104,12 +104,15 @@ static struct genbind_node *
add_method(struct genbind_node **genbind_ast,
long methodtype,
struct genbind_node *declarator,
- char *cdata)
+ char *cdata,
+ int lineno,
+ char *filename)
{
struct genbind_node *res_node;
struct genbind_node *method_node;
struct genbind_node *class_node;
struct genbind_node *cdata_node;
+ struct genbind_node *location_node;
char *class_name;
/* extract the class name from the declarator */
@@ -131,11 +134,18 @@ add_method(struct genbind_node **genbind_ast,
cdata);
}
+
+ location_node = genbind_new_node(GENBIND_NODE_TYPE_FILE,
+ genbind_new_node(GENBIND_NODE_TYPE_LINE,
+ cdata_node,
+ (void *)lineno),
+ strdup(filename));
+
/* generate method node */
method_node = genbind_new_node(GENBIND_NODE_TYPE_METHOD,
NULL,
genbind_new_node(GENBIND_NODE_TYPE_METHOD_TYPE,
- cdata_node,
+ location_node,
(void *)methodtype));
class_node = genbind_node_find_type_ident(*genbind_ast,
@@ -396,12 +406,12 @@ ParameterList:
Method:
MethodType MethodDeclarator CBlock
{
- $$ = add_method(genbind_ast, $1, $2, $3);
+ $$ = add_method(genbind_ast, $1, $2, $3, @1.first_line, @1.filename);
}
|
MethodType MethodDeclarator ';'
{
- $$ = add_method(genbind_ast, $1, $2, NULL);
+ $$ = add_method(genbind_ast, $1, $2, NULL, @1.first_line, @1.filename);
}
;