summaryrefslogtreecommitdiff
path: root/tools/npl
diff options
context:
space:
mode:
authorJakub Zawadzki <darkjames-ws@darkjames.pl>2013-03-09 15:53:30 +0000
committerJakub Zawadzki <darkjames-ws@darkjames.pl>2013-03-09 15:53:30 +0000
commit7b9a23a53a4b50acd5fd7ca44bdb3168f26033c2 (patch)
treea851d0fd94e08aad69de599798069125a1171df0 /tools/npl
parent91cec2a12e137aebc55d4e7a901ed25c222025d3 (diff)
downloadwireshark-7b9a23a53a4b50acd5fd7ca44bdb3168f26033c2.tar.gz
[NPL] Misc fixes
svn path=/trunk/; revision=48216
Diffstat (limited to 'tools/npl')
-rw-r--r--tools/npl/ast.h43
-rw-r--r--tools/npl/npl.c349
-rw-r--r--tools/npl/parser.l97
-rw-r--r--tools/npl/xmem.h2
4 files changed, 391 insertions, 100 deletions
diff --git a/tools/npl/ast.h b/tools/npl/ast.h
index 8f3b082532..6bc86e1fed 100644
--- a/tools/npl/ast.h
+++ b/tools/npl/ast.h
@@ -53,6 +53,7 @@ typedef enum {
EXPRESSION_STR,
EXPRESSION_INDEX,
+ EXPRESSION_MULTI_INDEX,
EXPRESSION_FIELD,
EXPRESSION_CALL,
@@ -62,6 +63,12 @@ typedef enum {
} npl_expression_type_t;
+typedef struct _npl_expression_list {
+ struct _npl_expression_list *next;
+
+ struct _npl_expression *expr;
+} npl_expression_list_t;
+
typedef struct _npl_expression {
union {
struct {
@@ -91,6 +98,13 @@ union {
} arr;
struct {
+ npl_expression_type_t type; /* EXPRESSION_MULTI_INDEX */
+
+ struct _npl_expression *base;
+ npl_expression_list_t *indexes;
+ } aarr;
+
+ struct {
npl_expression_type_t type; /* EXPRESSION_FIELD */
struct _npl_expression *base;
@@ -118,13 +132,7 @@ union {
npl_expression_type_t type; /* EXPRESSION_CALL */
struct _npl_expression *fn;
-
- struct _npl_expression_list {
- struct _npl_expression_list *next;
-
- struct _npl_expression *expr;
-
- } *args;
+ npl_expression_list_t *args;
} call;
@@ -222,7 +230,7 @@ typedef struct _npl_statement {
} w;
struct {
- npl_statement_type_t type; /* STATEMTN_TABLE */
+ npl_statement_type_t type; /* STATEMENT_TABLE */
npl_table_t data;
} t;
@@ -251,7 +259,8 @@ typedef struct _npl_statement {
npl_expression_t *format;
struct _npl_statements *sts;
- struct hfinfo *hfi; /* set by code gen */
+ /* after 1st pass of code generator */
+ struct hfinfo *hfi;
} f;
};
@@ -292,12 +301,16 @@ typedef struct {
npl_expression_t *display_format;
npl_expression_t *size;
+ /* after 1st pass of code generator */
+ const char *hf_type;
+
} npl_type_t;
typedef enum {
DECL_INVALID = 0,
DECL_ATTR,
+ DECL_INCLUDE,
DECL_STRUCT,
DECL_TABLE,
DECL_CONST,
@@ -306,8 +319,8 @@ typedef enum {
} npl_decl_type_t;
-typedef struct _npl_attr {
- npl_expression_t expr;
+typedef struct {
+ npl_expression_list_t *expr_list;
} npl_attr_t;
typedef struct {
@@ -323,6 +336,12 @@ typedef struct {
} a;
struct {
+ npl_decl_type_t type; /* DECL_INCLUDE */
+
+ char *file;
+ } i;
+
+ struct {
npl_decl_type_t type; /* DECL_STRUCT */
npl_struct_t data;
@@ -362,6 +381,4 @@ typedef struct {
} *decls;
- int parse_ok;
-
} npl_code_t;
diff --git a/tools/npl/npl.c b/tools/npl/npl.c
index 1ac324fe03..56b80c94d2 100644
--- a/tools/npl/npl.c
+++ b/tools/npl/npl.c
@@ -25,7 +25,7 @@
#include "ast.h"
#include "xmem.h"
-void npl_parse_file(npl_code_t *code, FILE *f, const char *filename); /* parser.l */
+int npl_parse_file(npl_code_t *code, FILE *f, const char *filename); /* parser.l */
static void gen_expr(FILE *f, npl_expression_t *e);
static void gen_statements(FILE *f, struct _npl_statements *sts);
@@ -39,6 +39,16 @@ struct hfinfo {
struct hfinfo *hfs;
+static void _fail(const char *file, int line, const char *msg) {
+ fprintf(stderr, "!!! %s:%d fail(%s)\n", file, line, msg);
+ abort();
+}
+
+#define fail(msg) _fail(__FILE__, __LINE__, msg)
+
+#define xassert(expr) \
+ do { if (!(expr)) fail("Assertion failed: " #expr); } while(0);
+
static struct hfinfo *
add_hfi(npl_statement_t *st)
@@ -57,8 +67,9 @@ add_hfi(npl_statement_t *st)
}
static const char *
-hfi_name(const struct hfinfo *hfi)
+hfi_var(const struct hfinfo *hfi)
{
+ /* XXX nicer name */
static char hf_name[64];
snprintf(hf_name, sizeof(hf_name), "hf_field_%u", hfi->id);
@@ -66,6 +77,127 @@ hfi_name(const struct hfinfo *hfi)
return hf_name;
}
+static const char *
+hfi_name(const struct hfinfo *hfi)
+{
+ return hfi->st->f.id;
+}
+
+static const char *
+hfi_filter(const struct hfinfo *hfi)
+{
+ /* TODO stub */
+ return "";
+}
+
+static const char *
+hfi_type(const struct hfinfo *hfi)
+{
+ /* TODO stub */
+ return "FT_BYTES";
+}
+
+static const char *
+hfi_display(const struct hfinfo *hfi)
+{
+ /* TODO stub */
+ return "BASE_NONE";
+}
+
+static unsigned int
+hfi_mask(const struct hfinfo *hfi)
+{
+ /* TODO stub */
+ return 0;
+}
+
+static int
+expr_to_int(const npl_expression_t *npl, int *val)
+{
+ if (npl->type == EXPRESSION_INT) {
+ *val = npl->num.digit;
+ return 1;
+ }
+ if (npl->type == EXPRESSION_UNARY) {
+ if (!expr_to_int(npl->u.operand, val))
+ return 0;
+
+ switch (npl->u.operator) {
+ case OP1_MINUS:
+ *val = -(*val);
+ return 1;
+ case OP1_NEG:
+ *val = ~(*val);
+ return 1;
+ case OP1_NOT:
+ *val = !(*val);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static int
+expr_to_str(const npl_expression_t *npl, const char **val)
+{
+ if (npl->type == EXPRESSION_STR) {
+ *val = npl->str.str;
+ return 1;
+ }
+ return 0;
+}
+
+static const char *
+type_to_ft(const npl_type_t *t, int size)
+{
+ switch (t->type) {
+ case FIELD_DECIMAL:
+ if (size == 4)
+ return "FT_FLOAT";
+ if (size == 8)
+ return "FT_DOUBLE";
+
+ fprintf(stderr, "!!! decimal, size: %d\n", size);
+ return NULL;
+
+ case FIELD_NUMBER:
+ if (size == 1)
+ return "FT_INT8";
+ if (size == 2)
+ return "FT_INT16";
+ if (size == 3)
+ return "FT_INT24";
+ if (size == 4)
+ return "FT_INT32";
+ if (size <= 8)
+ return "FT_INT64";
+
+ fprintf(stderr, "!!! number, size: %d\n", size);
+ return NULL;
+
+ case FIELD_UNSIGNED_NUMBER:
+ if (size == 1)
+ return "FT_UINT8";
+ if (size == 2)
+ return "FT_UINT16";
+ if (size == 3)
+ return "FT_UINT24";
+ if (size == 4)
+ return "FT_UINT32";
+ if (size <= 8)
+ return "FT_UINT64";
+
+ fprintf(stderr, "!!! number, size: %d\n", size);
+ return NULL;
+
+ case FIELD_TIME:
+ /* XXX, FT_ABSOLUTE_TIME or FT_RELATIVE_TIME? */
+ fprintf(stderr, "!!! time, size: %d\n", size);
+ return "FT_ABSOLUTE_TIME";
+ }
+ fprintf(stderr, "!!! not handled, type: %d, size: %d\n", t->type, size);
+ return NULL;
+}
#define gen_fprintf(f, args...) \
do { \
@@ -160,7 +292,7 @@ gen_expr(FILE *f, npl_expression_t *e)
case EXPRESSION_CALL:
{
- struct _npl_expression_list *arg;
+ npl_expression_list_t *arg;
char *ind = "";
gen_expr(f, e->call.fn);
@@ -173,12 +305,101 @@ gen_expr(FILE *f, npl_expression_t *e)
gen_fprintf(f, ")");
return;
}
+
+ case EXPRESSION_FIELD:
+ gen_expr(f, e->fld.base);
+ gen_fprintf(f, ".%s ", e->fld.field);
+ return;
}
fprintf(stderr, "XXXX expr->type: %d\n", e->type);
}
+static int
+gen_table_struct(FILE *f, npl_table_t *t)
+{
+ enum { CANT, VALUE_STRING, STRING_STRING } type;
+ struct npl_table_case *c;
+
+ int all_int = 1;
+ int all_str = 1;
+
+ if (t->params.count || !t->switch_expr || t->default_expr)
+ return 0;
+
+ for (c = t->cases; c; c = c->next) {
+ const char *str;
+ int val;
+
+ if (!c->return_expr || !expr_to_str(c->return_expr, &str))
+ return 0;
+
+ if (all_int && !expr_to_int(&c->e, &val))
+ all_int = 0;
+ if (all_str && !expr_to_str(&c->e, &str))
+ all_str = 0;
+
+ if (!all_int && !all_str)
+ return 0;
+ }
+
+ if (all_int)
+ type = VALUE_STRING;
+ else if (all_str)
+ type = STRING_STRING;
+ else
+ type = CANT;
+
+ /* table can be converted to value_string, generate one */
+ if (f && type == VALUE_STRING) {
+ gen_fprintf(f,
+ "static const value_string %s[] = {\n",
+ t->id);
+
+ for (c = t->cases; c; c = c->next) {
+ const char *str;
+ int val;
+
+ /* checked above, should not fail now */
+ if (!expr_to_str(c->return_expr, &str))
+ fail("expr_to_str(str)");
+ if (!expr_to_int(&c->e, &val))
+ fail("expr_to_int(val)");
+
+ gen_fprintf(f, "\t{ %x, \"%s\" },\n", val, str);
+ }
+ gen_fprintf(f, "\t{ 0, NULL }\n");
+ gen_fprintf(f, "};\n");
+ return 1;
+ }
+
+ /* table can be converted to string_string, generate one */
+ if (f && type == STRING_STRING) {
+ gen_fprintf(f,
+ "static const string_string %s[] = {\n",
+ t->id);
+
+ for (c = t->cases; c; c = c->next) {
+ const char *str;
+ const char *val;
+
+ /* checked above, should not fail now */
+ if (!expr_to_str(c->return_expr, &str))
+ fail("expr_to_str(str)");
+ if (!expr_to_str(&c->e, &val))
+ fail("expr_to_str(val)");
+
+ gen_fprintf(f, "\t{ \"%s\", \"%s\" },\n", val, str);
+ }
+ gen_fprintf(f, "\t{ NULL, NULL }\n");
+ gen_fprintf(f, "};\n");
+ return 1;
+ }
+
+ return 0;
+}
+
static void
-gen_table(FILE *f, npl_table_t *t)
+gen_table_func(FILE *f, npl_table_t *t)
{
struct npl_table_case *c;
@@ -215,8 +436,7 @@ again1:
if (!c->return_expr) {
c = c->next;
- if (!c)
- abort();
+ xassert(c != NULL);
gen_fprintf(f, "\n");
goto again1;
} else {
@@ -244,8 +464,7 @@ again2:
if (!c->return_expr) {
gen_fprintf(f, " || ");
c = c->next;
- if (!c)
- abort();
+ xassert(c != NULL);
goto again2;
} else {
gen_fprintf(f, ")\n");
@@ -265,6 +484,14 @@ again2:
gen_fprintf(f, "\treturn \"\";\n");
gen_fprintf(f, "}\n");
+}
+
+static void
+gen_table(FILE *f, npl_table_t *t)
+{
+ if (!gen_table_struct(f, t))
+ gen_table_func(f, t);
+
gen_fprintf(f, "\n");
}
@@ -297,7 +524,7 @@ gen_statement(FILE *f, npl_statement_t *st)
if (f) {
// XXX, search for st->f.t_id in table.
- gen_fprintf(f, "\toffset = dissect_%s(tvb, tree, %s, offset);\n", st->f.t_id, hfi_name(st->f.hfi));
+ gen_fprintf(f, "\toffset = dissect_%s(tvb, tree, %s, offset);\n", st->f.t_id, hfi_var(st->f.hfi));
}
// XXX st->f.bits, st->f.arr, st->f.format, st->f.sts
return;
@@ -336,7 +563,6 @@ gen_statement(FILE *f, npl_statement_t *st)
return;
}
-
if (c) {
npl_statement_t *default_st = st->sw.data.default_st;
@@ -413,6 +639,8 @@ gen_protocol(FILE *f, npl_protocol_t *p)
gen_fprintf(f, "{\n");
gen_fprintf(f,
"\tint offset = 0;\n"
+ "\tproto_tree *tree = NULL;\n"
+ "\tproto_item *ti = NULL;\n"
"\n"
);
@@ -439,8 +667,7 @@ gen_struct(FILE *f, npl_struct_t *s)
snprintf(id, sizeof(id), "_noname%u", ++_id);
s->id = xstrdup(id);
- if (f != NULL)
- abort();
+ xassert(f == NULL);
}
if (s->count_expr) {
@@ -498,25 +725,40 @@ gen_struct(FILE *f, npl_struct_t *s)
static void
gen_const(FILE *f, npl_const_t *c)
{
-// TODO
- fprintf(stderr, "gen_const() TODO\n");
+ // TODO, later don't do #define, only add to id table with given value.
+
+ gen_fprintf(f, "#define %s", c->id);
+ gen_expr(f, &c->expr);
+ gen_fprintf(f, "\n");
}
static void
gen_type(FILE *f, npl_type_t *t)
{
+ int size = -1;
+ int byte_order = -1;
+ const char *hf_type = NULL;
+
gen_fprintf(f,
"static int\n"
- "dissect_type_%s(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)\n"
+ "dissect_type_%s(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int hf, int offset)\n"
"{\n", t->name);
-#if 0
- npl_params_t params;
+ if (t->params.count) {
+ /* XXX */
+ fprintf(stderr, "XXX, t->params.count\n");
+ }
- npl_expression_t *byte_order;
- npl_expression_t *display_format;
- npl_expression_t *size;
-#endif
+ if (t->size && !expr_to_int(t->size, &size))
+ fprintf(stderr, "!!! expr_to_int(size) failed for type: %s\n", t->name);
+
+ if (t->byte_order && !expr_to_int(t->byte_order, &byte_order))
+ fprintf(stderr, "!!! expr_to_int(byte_order) failed for type: %s\n", t->name);
+
+ hf_type = type_to_ft(t, size);
+ /* npl_expression_t *display_format; */
+
+ t->hf_type = hf_type ? hf_type : "FT_BYTES";
gen_fprintf(f, "\treturn offset;\n");
gen_fprintf(f, "}\n");
@@ -526,8 +768,7 @@ gen_type(FILE *f, npl_type_t *t)
static void
gen_attr(FILE *f, npl_attr_t *a)
{
-// TODO
- fprintf(stderr, "gen_attr() TODO");
+ fprintf(stderr, "gen_attr() TODO\n");
}
static void
@@ -571,13 +812,11 @@ gen_hf(FILE *f)
struct hfinfo *hfi;
for (hfi = hfs; hfi; hfi = hfi->next)
- gen_fprintf(f, "static int %s = -1;\n", hfi_name(hfi));
+ gen_fprintf(f, "static int %s = -1;\n", hfi_var(hfi));
}
-static const char proto_name[] = "foo"; /* TODO, hardcoded */
-
static void
-gen_proto_register(FILE *f)
+gen_proto_register(FILE *f, const char *proto_name)
{
struct hfinfo *hfi;
@@ -589,15 +828,14 @@ gen_proto_register(FILE *f)
/* hf array */
gen_fprintf(f, "\tstatic hf_register_info hf[] = {\n");
for (hfi = hfs; hfi; hfi = hfi->next) {
- npl_statement_t *st = hfi->st;
-
- gen_fprintf(f,
+ gen_fprintf(f,
"\t\t{ &%s,\n"
"\t\t\t{ \"%s\", \"%s\", %s, %s, NULL, 0x%.2x, NULL, HFILL }\n"
- "\t\t},\n", hfi_name(hfi), st->f.id, "filtr", "typ", "dec", 0x00 );
+ "\t\t},\n", hfi_var(hfi), hfi_name(hfi), hfi_filter(hfi), hfi_type(hfi), hfi_display(hfi), hfi_mask(hfi) );
}
gen_fprintf(f, "\t}\n\n");
+ /* ett array */
gen_fprintf(f, "\tstatic gint *ett[] = {\n");
#if 0
&ett_foo,
@@ -615,14 +853,14 @@ gen_proto_register(FILE *f)
}
static void
-gen_proto_handoff(FILE *f)
+gen_proto_handoff(FILE *f, const char *proto_name)
{
gen_fprintf(f,
"void\n"
"proto_reg_handoff_%s(void)\n"
- "{", proto_name);
+ "{\n", proto_name);
- gen_fprintf(f, "dissector_handle_t %s_handle = new_create_dissector_handle(dissect_%s, proto_%s);\n", proto_name, proto_name, proto_name);
+ gen_fprintf(f, "\tdissector_handle_t %s_handle = new_create_dissector_handle(dissect_%s, proto_%s);\n", proto_name, proto_name, proto_name);
#if 0
dissector_add_uint("REG", XXX, %s_handle);
@@ -632,10 +870,24 @@ gen_proto_handoff(FILE *f)
gen_fprintf(f, "}\n");
}
+static const npl_protocol_t *
+get_protocol(npl_code_t *code)
+{
+ struct _npl_decl_list *decl;
+
+ for (decl = code->decls; decl; decl = decl->next) {
+ /* XXX, for now return first */
+ if (decl->d.type == DECL_PROTOCOL)
+ return &decl->d.p.data;
+ }
+ return NULL;
+}
+
int main(int argc, char **argv) {
FILE *f;
npl_code_t code;
-
+ int parse_ok;
+
if (argc != 2) {
fprintf(stderr, "usage: %s filename\n", argv[0]);
return 1;
@@ -647,25 +899,36 @@ int main(int argc, char **argv) {
}
memset(&code, 0, sizeof(code));
- printf("%s:\n", argv[1]);
- npl_parse_file(&code, f, argv[1]);
-
- if (code.parse_ok) {
+ parse_ok = npl_parse_file(&code, f, argv[1]);
+// parse_ok = 0;
+ if (parse_ok) {
+ const npl_protocol_t *proto = get_protocol(&code);
+ const char *proto_name = (proto) ? proto->id : "noname";
FILE *out;
gen_code(NULL, &code);
out = fopen("/tmp/npl.c", "w");
- /* TODO declare ett_ */
+ /* includes */
+ gen_fprintf(out, "#include \"config.h\"\n");
+ gen_fprintf(out, "#include <glib.h>\n");
+ gen_fprintf(out, "#include <epan/packet.h>\n");
+ gen_fprintf(out, "\n");
+
+ /* TODO declare forward */
+
+ gen_fprintf(out, "static int proto_%s = -1;\n", proto_name);
gen_hf(out);
+ gen_fprintf(out, "\n");
- gen_fprintf(out, "\n\n");
+ /* TODO declare ett_ */
+ gen_fprintf(out, "\n");
gen_code(out, &code);
- gen_proto_register(out);
- gen_proto_handoff(out);
+ gen_proto_register(out, proto_name);
+ gen_proto_handoff(out, proto_name);
fclose(out);
}
diff --git a/tools/npl/parser.l b/tools/npl/parser.l
index d0d479974b..105b0781aa 100644
--- a/tools/npl/parser.l
+++ b/tools/npl/parser.l
@@ -485,7 +485,6 @@ parse_params(npl_params_t *p)
static void parse_expression(npl_expression_t *expr);
static npl_expression_t *xparse_expression(void);
-static npl_expression_t g_e;
static void
parse_primary(npl_expression_t *expr)
@@ -531,6 +530,22 @@ parse_primary(npl_expression_t *expr)
nomatch();
}
+/* ExpressionList = Expression, { ",", Expression } ; */
+static void
+parse_expression_list(npl_expression_list_t **ptr)
+{
+ do {
+ npl_expression_list_t *cur = xnew(npl_expression_list_t);
+
+ *ptr = cur;
+ ptr = &(cur->next);
+ cur->expr = xparse_expression();
+
+ } while (is_token_accept(TOKEN_COMMA));
+
+ *ptr = NULL;
+}
+
static void
parse_expression1(npl_expression_t *expr)
{
@@ -539,44 +554,33 @@ parse_expression1(npl_expression_t *expr)
do {
if (is_token_accept(TOKEN_LPAREN)) { /* foo() */
npl_expression_t *fun = xdup(npl_expression_t, expr);
- struct _npl_expression_list **ptr = &(expr->call.args);
-
- if (!is_token(TOKEN_RPAREN)) {
- do {
- struct _npl_expression_list *cur = xnew(struct _npl_expression_list);
-
- *ptr = cur;
- ptr = &(cur->next);
- cur->expr = xparse_expression();
-
- } while (is_token_accept(TOKEN_COMMA));
- }
- *ptr = NULL;
+ npl_expression_list_t *args = NULL;
+ if (!is_token(TOKEN_RPAREN))
+ parse_expression_list(&args);
accept(TOKEN_RPAREN);
- expr->call.fn = fun;
+
expr->type = EXPRESSION_CALL;
+ expr->call.fn = fun;
+ expr->call.args = args;
- } else if (is_token(TOKEN_DOLLAR) || is_token(TOKEN_LBRACKET)) { /* arr$[field1, field2, ...], arr[10] */
+ } else if (is_token_accept(TOKEN_DOLLAR)) { /* arr$[field1, field2, ...] */
npl_expression_t *base = xdup(npl_expression_t, expr);
- npl_expression_t *idx;
- int aa;
+ npl_expression_list_t *indexes;
- aa = is_token_accept(TOKEN_DOLLAR);
accept(TOKEN_LBRACKET);
+ parse_expression_list(&indexes);
+ accept(TOKEN_RBRACKET);
- idx = xparse_expression();
-
- if (aa) {
- while (is_token_accept(TOKEN_COMMA)) {
- // XXX ast
-
- npl_expression_t *idx2;
+ expr->type = EXPRESSION_MULTI_INDEX;
+ expr->aarr.base = base;
+ expr->aarr.indexes = indexes;
- idx2 = xparse_expression();
- }
- }
+ } else if (is_token_accept(TOKEN_LBRACKET)) { /* arr[10] */
+ npl_expression_t *base = xdup(npl_expression_t, expr);
+ npl_expression_t *idx;
+ idx = xparse_expression();
accept(TOKEN_RBRACKET);
expr->type = EXPRESSION_INDEX;
@@ -921,21 +925,27 @@ static int is_attribute(void) { return is_token(TOKEN_LBRACKET); }
static void
parse_attributes(npl_attr_t *attr)
{
+ npl_expression_list_t **ptr = &attr->expr_list;
+
accept(TOKEN_LBRACKET);
do {
- parse_expression(&attr->expr);
+ npl_expression_list_t *cur = xnew(npl_expression_list_t);
+
+ *ptr = cur;
+ ptr = &(cur->next);
+ cur->expr = xparse_expression();
if (is_token_accept(TOKEN_SEMICOLON))
{ }
else if (is_token_accept(TOKEN_COMMA))
{ }
-
}
while (!is_token(TOKEN_RBRACKET));
// while (is_token_accept(TOKEN_COMMA));
accept(TOKEN_RBRACKET);
+ *ptr = NULL;
}
static void parse_statement(npl_statement_t *st);
@@ -1007,8 +1017,6 @@ parse_dynamic_switch(npl_switch_t *sw)
is_token_accept(TOKEN_SEMICOLON);
}
-static void parse_table(npl_table_t *);
-
static int is_statement(void) {
return
is_token(TOKEN_WHILE) ||
@@ -1076,6 +1084,7 @@ xparse_formatting(void)
return format;
}
+static void parse_table(npl_table_t *);
static void parse_struct(npl_struct_t *s, int statement);
static void
@@ -1128,12 +1137,12 @@ parse_statement(npl_statement_t *st)
if (is_token_accept(TOKEN_LPAREN)) {
/* XXX, WTF: StringTerm(Property.XMLEncoding, "<", true, false, false) Reason; */
+ npl_expression_list_t *type_params;
- do {
- /* XXX, ast */
- parse_expression(&g_e);
- } while (is_token_accept(TOKEN_COMMA));
+ parse_expression_list(&type_params);
accept(TOKEN_RPAREN);
+
+ /* XXX, store type_params in ast */
}
st->f.id = accept_id();
@@ -1375,13 +1384,12 @@ parse_decl(npl_decl_t *d)
parse_protocol(&d->p.data);
} else if (is_type()) {
- parse_type(&d->ty.data);
d->type = DECL_TYPE;
+ parse_type(&d->ty.data);
} else if (is_token_accept(TOKEN_INCLUDE)) {
- /* XXX, ast */
- char *file = accept_str();
- free(file);
+ d->type = DECL_INCLUDE;
+ d->i.file = accept_str(); /* XXX, it's C-escaped */ /* XXX, unix / vs dos \\ */
} else
nomatch();
@@ -1404,16 +1412,19 @@ parse_npl(npl_code_t *code)
*ptr = NULL;
}
-void
+int
npl_parse_file(npl_code_t *code, FILE *f, const char *filename)
{
+ int parse_ok = 0;
yyfilename = filename;
yyin = f;
next_token();
parse_npl(code);
- code->parse_ok = 1;
+ parse_ok = 1;
yylex_destroy();
+
+ return parse_ok;
}
diff --git a/tools/npl/xmem.h b/tools/npl/xmem.h
index d42065f040..173a88fd91 100644
--- a/tools/npl/xmem.h
+++ b/tools/npl/xmem.h
@@ -12,7 +12,7 @@ static inline void *xmalloc(size_t s) { void *ptr = malloc(s); if (!ptr) oom_kil
static inline void *xrealloc(void *p, size_t s) { void *ptr = realloc(p, s); if (!ptr) oom_killer(); return ptr; }
static inline void *xmemdup(void *p, size_t s) { void *ptr = malloc(s); if (!ptr) oom_killer(); return memcpy(ptr, p, s); }
-static inline void *xstrdup(const char *s) { void *ptr = strdup(s); if (!ptr) oom_killer(); return ptr; }
+static inline char *xstrdup(const char *s) { void *ptr = strdup(s); if (!ptr) oom_killer(); return ptr; }
#define xnew(x) (x *) xmalloc(sizeof(x))
#define xdup(x, y) (x *) xmemdup(y, sizeof(x))