summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorJakub Zawadzki <darkjames-ws@darkjames.pl>2013-03-31 15:03:46 +0000
committerJakub Zawadzki <darkjames-ws@darkjames.pl>2013-03-31 15:03:46 +0000
commitcbbf2b01e7101dd69156bc08c1399d57cdc368d0 (patch)
treed46f48a7047706946c29a960b161adf84bc3c922 /tools
parent84134c9e9cc69cd0ece2d78a8de2c8b126be4d64 (diff)
downloadwireshark-cbbf2b01e7101dd69156bc08c1399d57cdc368d0.tar.gz
[NPL] Pushing changes to wireshark repo
- parser no longer use abort() after failing - initial support for attributes - symbol hashing to avoid strcasecmp() - misc other fixes svn path=/trunk/; revision=48672
Diffstat (limited to 'tools')
-rw-r--r--tools/npl/ast.h38
-rw-r--r--tools/npl/npl.c716
-rw-r--r--tools/npl/parser.l76
3 files changed, 585 insertions, 245 deletions
diff --git a/tools/npl/ast.h b/tools/npl/ast.h
index 476a3ee79d..735a294fa9 100644
--- a/tools/npl/ast.h
+++ b/tools/npl/ast.h
@@ -223,14 +223,26 @@ typedef struct {
} npl_switch_t;
+typedef struct _npl_attribute_list {
+ struct _npl_attribute_list *next;
+ struct _npl_expression *expr;
+
+ /* code generator */
+ const char *resolved;
+ npl_expression_t *assign_expr;
+ int flags;
+} npl_attribute_list_t;
+
typedef struct _npl_statement {
union {
struct {
npl_statement_type_t type;
+ npl_attribute_list_t *attr_list;
};
struct {
npl_statement_type_t type; /* STATEMENT_WHILE */
+ npl_attribute_list_t *attr_list;
char *id;
npl_expression_t expr;
@@ -240,24 +252,28 @@ typedef struct _npl_statement {
struct {
npl_statement_type_t type; /* STATEMENT_TABLE */
+ npl_attribute_list_t *attr_list;
npl_table_t data;
} t;
struct {
npl_statement_type_t type; /* STATEMENT_STRUCT */
+ npl_attribute_list_t *attr_list;
npl_struct_t data;
} s;
struct {
npl_statement_type_t type; /* STATEMENT_SWITCH or STATEMENT_DYNAMIC_SWITCH */
+ npl_attribute_list_t *attr_list;
npl_switch_t data;
} sw;
struct _npl_statement_field {
npl_statement_type_t type; /* STATEMENT_FIELD */
+ npl_attribute_list_t *attr_list;
char *t_id;
char *id;
@@ -271,6 +287,7 @@ typedef struct _npl_statement {
/* code generator */
struct hfinfo *hfi;
+ npl_expression_t *byte_order_attr;
int generate_var;
} f;
@@ -290,6 +307,9 @@ typedef struct {
npl_expression_t *format;
struct _npl_statements *sts;
+ /* code generator */
+ struct symbol *sym;
+ npl_expression_t *byte_order_attr;
} npl_protocol_t;
typedef enum {
@@ -320,7 +340,6 @@ typedef struct {
typedef enum {
DECL_INVALID = 0,
- DECL_ATTR,
DECL_INCLUDE,
DECL_STRUCT,
DECL_TABLE,
@@ -331,53 +350,50 @@ typedef enum {
} npl_decl_type_t;
typedef struct {
- npl_expression_list_t *expr_list;
-} npl_attr_t;
-
-typedef struct {
union {
struct {
npl_decl_type_t type;
+ npl_attribute_list_t *attr_list;
};
struct {
- npl_decl_type_t type; /* DECL_ATTR */
-
- npl_attr_t data;
- } a;
-
- struct {
npl_decl_type_t type; /* DECL_INCLUDE */
+ npl_attribute_list_t *attr_list;
char *file;
} i;
struct {
npl_decl_type_t type; /* DECL_STRUCT */
+ npl_attribute_list_t *attr_list;
npl_struct_t data;
} s;
struct {
npl_decl_type_t type; /* DECL_TABLE */
+ npl_attribute_list_t *attr_list;
npl_table_t data;
} t;
struct {
npl_decl_type_t type; /* DECL_PROTOCOL */
+ npl_attribute_list_t *attr_list;
npl_protocol_t data;
} p;
struct {
npl_decl_type_t type; /* DECL_CONST */
+ npl_attribute_list_t *attr_list;
npl_const_t data;
} c;
struct {
npl_decl_type_t type; /* DECL_TYPE */
+ npl_attribute_list_t *attr_list;
npl_type_t data;
} ty;
diff --git a/tools/npl/npl.c b/tools/npl/npl.c
index 06515bf460..18e2f16f93 100644
--- a/tools/npl/npl.c
+++ b/tools/npl/npl.c
@@ -19,6 +19,7 @@
*/
#include <stdio.h>
+#include <ctype.h>
#include <string.h>
#include <stdlib.h>
@@ -27,10 +28,6 @@
int npl_parse_file(npl_code_t *code, FILE *f, const char *filename); /* parser.l */
-static struct symbol *gen_expr(FILE *f, npl_expression_t *e);
-static void gen_statements(FILE *f, struct _npl_statements *sts);
-static void gen_struct(FILE *f, npl_struct_t *s);
-
struct ettinfo {
struct ettinfo *next;
npl_struct_t *st;
@@ -39,8 +36,8 @@ struct ettinfo {
struct hfinfo {
struct hfinfo *next;
struct _npl_statement_field *st;
+ const char *parent;
- unsigned int id;
const char *hf_type;
};
@@ -52,18 +49,35 @@ enum symbol_type {
SYMBOL_TYPE = (1 << 3),
SYMBOL_FIELD = (1 << 4),
- SYMBOL_SIMPLE = (1 << 5)
+ SYMBOL_SIMPLE = (1 << 5),
+ SYMBOL_PROTO = (1 << 6),
};
struct symbol {
struct symbol *next;
const char *id;
+ void *data;
+
+ unsigned int hash;
enum symbol_type type;
+
int lvl;
- void *data;
+ int is_static:1;
+ int is_used:1;
+};
+
+struct parent_info {
+ const char *id;
+ npl_expression_t *byte_order;
+
+ /* size, offset, bitoffset, ... ? */
};
+static struct symbol *gen_expr(FILE *f, npl_expression_t *e);
+static void gen_statements(FILE *f, struct parent_info *parent, struct _npl_statements *sts);
+static void gen_struct(FILE *f, npl_struct_t *s, npl_attribute_list_t *attr_list);
+
struct symbol *symbols;
struct hfinfo *hfs;
struct ettinfo *etts;
@@ -104,13 +118,29 @@ symbols_pop(struct symbol *sym)
}
}
+static unsigned int
+symbol_hash(const char *str)
+{
+ unsigned int hash = 5381;
+
+ while (*str) {
+ hash = ((hash << 5) + hash) + tolower(*str);
+ str++;
+ }
+
+ return hash;
+}
+
static struct symbol *
symbol_find(const char *id, int type)
{
struct symbol *sym;
+ unsigned int hash;
+
+ hash = symbol_hash(id);
for (sym = symbols; sym; sym = sym->next) {
- if (!strcasecmp(sym->id, id)) {
+ if (sym->hash == hash && !strcasecmp(sym->id, id)) {
// XXX, check type
return sym;
}
@@ -135,6 +165,7 @@ symbol_add(const char *id, enum symbol_type type, void *data)
sym = xnew(struct symbol);
sym->id = id;
+ sym->hash = symbol_hash(id);
sym->type = type;
sym->lvl = symbols_lvl;
sym->data = data;
@@ -169,14 +200,12 @@ ett_var(const struct ettinfo *ett)
}
static struct hfinfo *
-hfi_add(struct _npl_statement_field *st)
+hfi_add(struct _npl_statement_field *st, const struct parent_info *parent)
{
- static unsigned int _hf_id = 0;
-
struct hfinfo *new = xnew(struct hfinfo);
new->st = st;
- new->id = ++_hf_id;
+ new->parent = parent->id;
new->next = hfs;
hfs = new;
@@ -184,13 +213,54 @@ hfi_add(struct _npl_statement_field *st)
return new;
}
+static size_t
+hfi_put_name(char *buf, size_t buflen, const char *str)
+{
+ size_t pos = 0;
+ int i;
+
+ int t = 0;
+ int toldup = -1;
+
+ for (i = 0; str[i]; i++) {
+ int tup = isupper(str[i]);
+
+ if (toldup != tup && tup) {
+ if (t > 0) {
+ if (pos < buflen)
+ buf[pos++] = '_';
+ }
+ t++;
+ }
+ toldup = tup;
+
+ if (pos < buflen)
+ buf[pos++] = tolower(str[i]);
+ }
+ return pos;
+}
+
static const char *
hfi_var(const struct hfinfo *hfi)
{
- /* XXX nicer name */
- static char hf_name[64];
+ static char hf_name[256];
+ size_t pos;
+
+ pos = snprintf(hf_name, sizeof(hf_name), "hf_field_");
+ xassert(pos < sizeof(hf_name));
- snprintf(hf_name, sizeof(hf_name), "hf_field_%u", hfi->id);
+ if (hfi->parent) {
+ pos += hfi_put_name(hf_name + pos, sizeof(hf_name) - pos, hfi->parent);
+ xassert(pos < sizeof(hf_name));
+
+ hf_name[pos++] = '_';
+ xassert(pos < sizeof(hf_name));
+ }
+
+ pos += hfi_put_name(hf_name + pos, sizeof(hf_name) - pos, hfi->st->id);
+ xassert(pos < sizeof(hf_name));
+
+ hf_name[pos++] = '\0';
return hf_name;
}
@@ -204,8 +274,26 @@ hfi_name(const struct hfinfo *hfi)
static const char *
hfi_filter(const struct hfinfo *hfi)
{
- /* TODO stub */
- return "";
+ static char filter_name[1024];
+ size_t pos;
+
+ pos = 0;
+
+ if (hfi->parent) {
+ pos += hfi_put_name(filter_name + pos, sizeof(filter_name)-pos, hfi->parent);
+ xassert(pos < sizeof(filter_name));
+
+ filter_name[pos++] = '.';
+ xassert(pos < sizeof(filter_name));
+ }
+
+ pos += hfi_put_name(filter_name + pos, sizeof(filter_name)-pos, hfi->st->id);
+ xassert(pos < sizeof(filter_name));
+
+ filter_name[pos++] = '\0';
+ xassert(pos < sizeof(filter_name));
+
+ return filter_name;
}
static const char *
@@ -252,11 +340,11 @@ expr_to_symbol(const npl_expression_t *e)
const char *id = e->id.id;
sym = symbol_find(id, SYMBOL_ANY);
-
if (!sym) {
fprintf(stderr, "can't find id: %s\n", id);
abort();
}
+ /* XXX, sym->is_used */
if (sym->type == SYMBOL_EXPR) {
struct symbol *new_sym = expr_to_symbol(sym->data);
@@ -292,6 +380,7 @@ expr_to_const_int(const npl_expression_t *e, int *val)
*val = !(*val);
return 1;
}
+ return 0;
}
sym = expr_to_symbol(e);
@@ -330,7 +419,7 @@ type_to_ctype(const npl_type_t *t, int size)
fprintf(stderr, "!!! decimal, size: %d\n", size);
return NULL;
-
+
case FIELD_NUMBER:
if (size == 1)
return "gint8";
@@ -364,19 +453,22 @@ type_to_ctype(const npl_type_t *t, int size)
return NULL;
}
+#define NPL_ENDIAN_LE 0
+#define NPL_ENDIAN_BE 1
+
static const char *
type_to_tvb(const npl_type_t *t, int size, int endian)
{
switch (t->type) {
case FIELD_DECIMAL:
- if (size == 4 && endian == 0)
+ if (size == 4 && endian == NPL_ENDIAN_LE)
return "tvb_get_letohieee_float";
- if (size == 4 && endian == 1)
+ if (size == 4 && endian == NPL_ENDIAN_BE)
return "tvb_get_ntohieee_float";
- if (size == 8 && endian == 0)
+ if (size == 8 && endian == NPL_ENDIAN_LE)
return "tvb_get_letohieee_double";
- if (size == 8 && endian == 1)
+ if (size == 8 && endian == NPL_ENDIAN_BE)
return "tvb_get_ntohieee_double";
fprintf(stderr, "!!! decimal, size: %d, endian: %d\n", size, endian);
@@ -387,19 +479,19 @@ type_to_tvb(const npl_type_t *t, int size, int endian)
if (size == 1)
return "tvb_get_guint8";
- if (size == 2 && endian == 0)
+ if (size == 2 && endian == NPL_ENDIAN_LE)
return "tvb_get_letohs";
- if (size == 2 && endian == 1)
+ if (size == 2 && endian == NPL_ENDIAN_BE)
return "tvb_get_ntohs";
- if (t->type == FIELD_UNSIGNED_NUMBER && size == 3 && endian == 0)
+ if (t->type == FIELD_UNSIGNED_NUMBER && size == 3 && endian == NPL_ENDIAN_LE)
return "tvb_get_letoh24";
- if (t->type == FIELD_UNSIGNED_NUMBER && size == 3 && endian == 1)
+ if (t->type == FIELD_UNSIGNED_NUMBER && size == 3 && endian == NPL_ENDIAN_BE)
return "tvb_get_ntoh24";
- if (size == 4 && endian == 0)
+ if (size == 4 && endian == NPL_ENDIAN_LE)
return "tvb_get_letohl";
- if (size == 4 && endian == 1)
+ if (size == 4 && endian == NPL_ENDIAN_BE)
return "tvb_get_ntohl";
fprintf(stderr, "!!! number, size: %d, endian: %d\n", size, endian);
@@ -421,7 +513,7 @@ type_to_ft(const npl_type_t *t, int size)
fprintf(stderr, "!!! decimal, size: %d\n", size);
return NULL;
-
+
case FIELD_NUMBER:
if (size == 1)
return "FT_INT8";
@@ -520,6 +612,84 @@ op2_to_str(npl_op2_t op)
return "";
}
+
+static int
+resolve_attr_id(const char *id)
+{
+ if (!strcasecmp(id, "property"))
+ return 0;
+ if (!strcasecmp(id, "Global"))
+ return 1;
+ if (!strcasecmp(id, "local"))
+ return 2;
+ if (!strcasecmp(id, "conversation"))
+ return 3;
+ if (!strcasecmp(id, "post"))
+ return 4;
+
+ fprintf(stderr, ":: attr-id: %s\n", id);
+ return -1;
+}
+
+static int
+resolve_attr_expr(npl_attribute_list_t *attr, const struct _npl_expression *expr)
+{
+ int flags = 0;
+
+ switch (expr->type) {
+ case EXPRESSION_ID:
+ resolve_attr_id(expr->id.id);
+ break;
+
+ case EXPRESSION_FIELD:
+ flags |= resolve_attr_expr(attr, expr->fld.base);
+ resolve_attr_id(expr->fld.field);
+ break;
+
+ default:
+ fprintf(stderr, "resolve_attr_expr() %d\n", expr->type);
+ break;
+ }
+ return flags;
+}
+
+static void
+resolve_attr_list(npl_attribute_list_t *attr)
+{
+ while (attr) {
+ struct _npl_expression *expr = NULL;
+ const char *id = NULL;
+ int flags = 0;
+
+ if (attr->expr->type == EXPRESSION_BINARY && attr->expr->b.operator == OP2_ASSIGN) {
+ /* XXX, handle: a = b = c ? */
+ expr = attr->expr->b.operand1;
+ attr->assign_expr = attr->expr->b.operand2;
+ } else
+ expr = attr->expr;
+
+ switch (expr->type) {
+ case EXPRESSION_ID:
+ id = expr->id.id;
+ break;
+
+ case EXPRESSION_FIELD:
+ flags = resolve_attr_expr(attr, expr->fld.base);
+ id = expr->fld.field;
+ break;
+
+ default:
+ fprintf(stderr, "resolve_attr_list() expr: %d\n", expr->type);
+ break;
+ }
+
+ attr->flags = flags;
+ attr->resolved = id;
+
+ attr = attr->next;
+ }
+}
+
static void
gen_expr_field(FILE *f, struct _npl_statement_field *field)
{
@@ -561,6 +731,7 @@ gen_expr(FILE *f, npl_expression_t *e)
fprintf(stderr, "can't find id: %s\n", e->id.id);
abort();
}
+ sym->is_used = 1;
if (sym->type == SYMBOL_EXPR)
gen_expr(f, sym->data);
@@ -658,17 +829,18 @@ gen_expr(FILE *f, npl_expression_t *e)
return NULL;
}
-static int
+enum table_struct { TABLE_FULL, TABLE_VALUE_STRING, TABLE_STRING_STRING };
+
+static enum table_struct
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;
+ if (t->params.count > 1 || !t->switch_expr)
+ return TABLE_FULL;
for (c = t->cases; c; c = c->next) {
const char *str;
@@ -683,22 +855,16 @@ gen_table_struct(FILE *f, npl_table_t *t)
all_str = 0;
if (!all_int && !all_str)
- return 0;
+ return TABLE_FULL;
}
- 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) {
+ if (all_int) {
gen_fprintf(f,
- "static const value_string %s[] = {\n",
+ "static const value_string %s_vals[] = {\n",
t->id);
+ if (f)
for (c = t->cases; c; c = c->next) {
const char *str;
int val;
@@ -713,15 +879,16 @@ gen_table_struct(FILE *f, npl_table_t *t)
}
gen_fprintf(f, "\t{ 0, NULL }\n");
gen_fprintf(f, "};\n");
- return 1;
+ return TABLE_VALUE_STRING;
}
/* table can be converted to string_string, generate one */
- if (f && type == STRING_STRING) {
+ if (all_str) {
gen_fprintf(f,
- "static const string_string %s[] = {\n",
+ "static const string_string %s_vals[] = {\n",
t->id);
+ if (f)
for (c = t->cases; c; c = c->next) {
const char *str;
const char *val;
@@ -736,42 +903,17 @@ gen_table_struct(FILE *f, npl_table_t *t)
}
gen_fprintf(f, "\t{ NULL, NULL }\n");
gen_fprintf(f, "};\n");
- return 1;
+ return TABLE_STRING_STRING;
}
- return 0;
+ return TABLE_FULL;
}
static void
gen_table_func(FILE *f, npl_table_t *t)
{
- struct symbol *symroot;
struct npl_table_case *c;
- gen_fprintf(f,
- "static const char *\n"
- "format_table_%s", t->id);
-
- symroot = symbols_push();
-
- gen_fprintf(f, "(");
- if (t->params.count) {
- int i;
-
- for (i = 0; i < t->params.count; i++) {
- if (i)
- gen_fprintf(f, ", ");
- gen_fprintf(f, "TYPE %s", t->params.args[i]);
- symbol_add(t->params.args[i], SYMBOL_SIMPLE, t->params.args[i]);
- }
-
- } else {
- /* default */
- gen_fprintf(f, "TYPE value");
- symbol_add("value", SYMBOL_SIMPLE, "value");
- }
- gen_fprintf(f, ")\n{\n");
-
if (t->switch_expr) {
gen_fprintf(f, "\tswitch (");
gen_expr(f, t->switch_expr);
@@ -824,6 +966,67 @@ again2:
}
}
}
+}
+
+static void
+decl_table(npl_table_t *t)
+{
+ if (!t->sym)
+ t->sym = symbol_add(t->id, SYMBOL_TABLE, t);
+}
+
+static void
+gen_table(FILE *f, npl_table_t *t)
+{
+ struct symbol *symroot;
+ const char *first_arg;
+ enum table_struct type;
+
+ t->sym->is_static = 1;
+ gen_fprintf(f,
+ "static const char *\n"
+ "format_table_%s", t->id);
+
+ symroot = symbols_push();
+
+ gen_fprintf(f, "(");
+ if (t->params.count) {
+ int i;
+
+ for (i = 0; i < t->params.count; i++) {
+ if (i)
+ gen_fprintf(f, ", ");
+ gen_fprintf(f, "TYPE %s", t->params.args[i]);
+ symbol_add(t->params.args[i], SYMBOL_SIMPLE, t->params.args[i]);
+ }
+ first_arg = t->params.args[0];
+
+ } else {
+ /* default */
+ gen_fprintf(f, "TYPE value");
+ symbol_add("value", SYMBOL_SIMPLE, "value");
+ first_arg = "value";
+ }
+ gen_fprintf(f, ")\n{\n");
+
+ type = gen_table_struct(f, t);
+ switch (type) {
+ case TABLE_VALUE_STRING:
+ gen_fprintf(f, "\n");
+ gen_fprintf(f, "\tconst char *tmp = match_strval(%s_vals, %s);\n", t->id, first_arg);
+ gen_fprintf(f, "\tif (tmp)\n\t\treturn tmp;\n");
+ break;
+
+ case TABLE_STRING_STRING:
+ gen_fprintf(f, "\tconst char *tmp = match_strstr(%s_vals, %s);\n", t->id, first_arg);
+ gen_fprintf(f, "\tif (tmp)\n\t\treturn tmp;\n");
+ break;
+
+ case TABLE_FULL:
+ default:
+ gen_table_func(f, t);
+ break;
+ }
if (t->default_expr) {
gen_fprintf(f, "\treturn ");
@@ -832,54 +1035,69 @@ again2:
} else
gen_fprintf(f, "\treturn \"\";\n");
- gen_fprintf(f, "}\n");
+ gen_fprintf(f, "}\n\n");
symbols_pop(symroot);
}
static void
-decl_table(npl_table_t *t)
+gen_field_struct(FILE *f, struct _npl_statement_field *field, npl_struct_t *s)
{
- if (!t->sym)
- t->sym = symbol_add(t->id, SYMBOL_TABLE, t);
-}
+ // XXX st->f.bits, st->f.arr, st->f.format, st->f.sts
+ // XXX, st->f.generate_var
-static void
-gen_table(FILE *f, npl_table_t *t)
-{
- if (!gen_table_struct(f, t))
- gen_table_func(f, t);
+ gen_fprintf(f, "\toffset = dissect_struct_%s(tvb, pinfo, tree, %s, offset);\n", s->tmpid, hfi_var(field->hfi));
- gen_fprintf(f, "\n");
+ field->hfi->hf_type = "FT_BYTES";
}
static void
-gen_field_struct(FILE *f, npl_statement_t *st, npl_struct_t *s)
+gen_field_size(FILE *f, struct symbol *sym_size, int size)
{
- // XXX st->f.bits, st->f.arr, st->f.format, st->f.sts
- // XXX, st->f.generate_var
+ if (sym_size) {
+ /* runtime */
+ if (sym_size->type == SYMBOL_FIELD) {
+ gen_fprintf(f, "_field_%s", sym_size->id);
+
+ } else if (sym_size->type == SYMBOL_EXPR) {
+ gen_fprintf(f, "(");
+ gen_expr(f, sym_size->data);
+ gen_fprintf(f, ") ");
- gen_fprintf(f, "\toffset = dissect_struct_%s(tvb, pinfo, tree, %s, offset);\n", s->tmpid, hfi_var(st->f.hfi));
+ } else if (sym_size->type == SYMBOL_SIMPLE) {
+ gen_fprintf(f, "%s ", (const char *) sym_size->data);
- st->f.hfi->hf_type = "FT_BYTES";
+ } else {
+ fprintf(stderr, "::: %s (%d)\n", sym_size->id, sym_size->type);
+ gen_fprintf(f, "<<SYMBOL %s>>\n", sym_size->id);
+ }
+
+ } else {
+ /* const */
+ gen_fprintf(f, "%d", size);
+ }
}
static void
-gen_field_type(FILE *f, npl_statement_t *st, npl_type_t *t)
+gen_field_type(FILE *f, struct _npl_statement_field *field, npl_type_t *t)
{
struct symbol *symroot;
int i;
- // XXX st->f.bits, st->f.arr, st->f.sts
+ // XXX field.bits, field..arr, field..sts
int size = -1;
- struct symbol *sym_size = NULL;
+ struct symbol *size_sym = NULL;
int byte_order = -1;
- npl_expression_t *display_format = t->display_format;
+ npl_expression_t *byte_order_expr;
+ struct symbol *byte_order_sym = NULL;
+
+ npl_expression_t *display_format;
+
const char *hf_type;
- npl_expression_list_t *argv = st->f.params;
+ npl_expression_list_t *argv = field->params;
int argc = count_expression_list(argv);
if (t->params.count != argc) {
@@ -896,19 +1114,33 @@ gen_field_type(FILE *f, npl_statement_t *st, npl_type_t *t)
xassert(t->size != NULL);
if (!expr_to_const_int(t->size, &size)) {
- sym_size = expr_to_symbol(t->size);
+ size_sym = expr_to_symbol(t->size);
- if (!sym_size) {
+ if (!size_sym) {
fprintf(stderr, "!!! expr_to_const_int, _symbol(size) failed for type: %s\n", t->id);
abort();
}
}
- if (t->byte_order && !expr_to_const_int(t->byte_order, &byte_order))
- fprintf(stderr, "!!! expr_to_const_int(byte_order) failed for type: %s\n", t->id);
+ if (field->byte_order_attr)
+ byte_order_expr = field->byte_order_attr;
+ else if (t->byte_order)
+ byte_order_expr = t->byte_order;
+ else
+ byte_order_expr = NULL;
+
+ if (byte_order_expr) {
+ if (!expr_to_const_int(byte_order_expr, &byte_order)) {
+ byte_order_sym = expr_to_symbol(byte_order_expr);
+ if (!byte_order_sym) {
+ fprintf(stderr, "!!! expr_to_const_int, _symbol(byte_order) failed for type: %s\n", t->id);
+ abort();
+ }
+ }
+ }
- if (st->f.generate_var) {
- /* XXX, sym_size */
+ if (field->generate_var) {
+ /* XXX, size_sym, byte_order_sym */
const char *ctype = type_to_ctype(t, size);
const char *fetch_func = type_to_tvb(t, size, byte_order);
@@ -919,29 +1151,31 @@ gen_field_type(FILE *f, npl_statement_t *st, npl_type_t *t)
*/
/* XXX, we should declare variable on begin of block (< C99) */
- gen_fprintf(f, "\t%s _field_%s = %s(tvb, offset);\n", ctype, st->f.id, fetch_func);
+ gen_fprintf(f, "\t%s _field_%s = %s(tvb, offset);\n", ctype, field->id, fetch_func);
}
- if (sym_size) {
- if (sym_size->type == SYMBOL_FIELD) {
- struct _npl_statement_field *field = sym_size->data;
+ if (size_sym) {
+ if (size_sym->type == SYMBOL_FIELD) {
+ struct _npl_statement_field *sym_field = size_sym->data;
- xassert(field->generate_var || f == NULL);
+ xassert(sym_field->generate_var || f == NULL);
- field->generate_var = 1;
+ sym_field->generate_var = 1;
} else
- fprintf(stderr, "::: %s (%d)\n", sym_size->id, sym_size->type);
+ fprintf(stderr, "::: %s (%d)\n", size_sym->id, size_sym->type);
hf_type = NULL;
} else
hf_type = type_to_ft(t, size);
- st->f.hfi->hf_type = hf_type;
+ field->hfi->hf_type = hf_type;
/* prefer statement format over type one (?) */
- if (st->f.format)
- display_format = st->f.format;
+ if (field->format)
+ display_format = field->format;
+ else
+ display_format = t->display_format;
/* XXX, when generate_var we can use fetched value, not proto_tree_add_item() */
@@ -950,43 +1184,78 @@ gen_field_type(FILE *f, npl_statement_t *st, npl_type_t *t)
fprintf(stderr, "XXX, format\n");
else
#endif
- gen_fprintf(f, "\tproto_tree_add_item(tree, %s, tvb, offset, %d, %s); ",
- hfi_var(st->f.hfi),
- size,
- (byte_order == 0) ? "ENC_LITTLE_ENDIAN" :
- (byte_order == 1) ? "ENC_BIG_ENDIAN" :
+ gen_fprintf(f, "\tproto_tree_add_item(tree, %s, tvb, offset, ", hfi_var(field->hfi));
+ /* XXX, emit temporary variable? expressions might be time-consuming, we could also check if size < 0 */
+ gen_field_size(f, size_sym, size);
+ gen_fprintf(f, ", %s);\n",
+ (byte_order == NPL_ENDIAN_LE) ? "ENC_LITTLE_ENDIAN" :
+ (byte_order == NPL_ENDIAN_BE) ? "ENC_BIG_ENDIAN" :
"ENC_NA");
- if (sym_size) {
- /* runtime */
- if (sym_size->type == SYMBOL_FIELD) {
- gen_fprintf(f, "offset += _field_%s;\n", sym_size->id);
+ gen_fprintf(f, "\toffset += ");
+ gen_field_size(f, size_sym, size);
+ gen_fprintf(f, ";\n");
- } else if (sym_size->type == SYMBOL_EXPR) {
- gen_fprintf(f, "\n\t");
- gen_fprintf(f, "offset += (");
- gen_expr(f, sym_size->data);
- gen_fprintf(f, ");\n");
+ symbols_pop(symroot);
+}
- } else if (sym_size->type == SYMBOL_SIMPLE) {
- gen_fprintf(f, "offset += %s;\n", (const char *) sym_size->data);
+static void
+gen_statement_field(FILE *f, struct parent_info *parent, struct _npl_statement_field *field, npl_attribute_list_t *attr_list)
+{
+ struct symbol *sym;
- } else {
- fprintf(stderr, "::: %s (%d)\n", sym_size->id, sym_size->type);
- gen_fprintf(f, "offset += XXX;\n");
- }
+ if (!field->hfi) {
+ field->hfi = hfi_add(field, parent);
+ xassert(f == NULL);
+ }
- } else {
- /* const */
- gen_fprintf(f, "offset += %d;\n", size);
+ sym = symbol_find(field->t_id, SYMBOL_STRUCT | SYMBOL_TYPE);
+ if (!sym) {
+ fprintf(stderr, "can't find: %s\n", field->t_id);
+ abort();
}
+ sym->is_used = 1;
- symbols_pop(symroot);
+ symbol_add(field->id, SYMBOL_FIELD, field);
+
+ field->byte_order_attr = parent->byte_order;
+
+ /* already resolved */
+ while (attr_list) {
+ const char *attr_name = attr_list->resolved;
+ npl_expression_t *attr_expr = attr_list->assign_expr;
+ int flags = attr_list->flags;
+
+ if (attr_name) {
+ if (!strcasecmp(attr_name, "DataFieldByteOrder")) {
+ xassert(flags == 0);
+ xassert(attr_expr != NULL);
+
+ field->byte_order_attr = attr_expr;
+ } else
+ fprintf(stderr, "!!! generating field attr: %s not handled!\n", attr_name);
+ } else
+ fprintf(stderr, "!!! generating field attr: not resolved!\n");
+
+ attr_list = attr_list->next;
+ }
+
+ if (sym->type == SYMBOL_STRUCT)
+ gen_field_struct(f, field, sym->data);
+ else if (sym->type == SYMBOL_TYPE)
+ gen_field_type(f, field, sym->data);
+ else {
+ /* XXX, SYMBOL_TABLE? */
+ fprintf(stderr, "%s: wrong type [%d]\n", sym->id, sym->type);
+ abort();
+ }
}
static void
-gen_statement(FILE *f, npl_statement_t *st)
+gen_statement(FILE *f, struct parent_info *parent, npl_statement_t *st)
{
+ resolve_attr_list(st->attr_list);
+
switch (st->type) {
case STATEMENT_WHILE:
// XXX ->id
@@ -994,46 +1263,20 @@ gen_statement(FILE *f, npl_statement_t *st)
gen_expr(f, &st->w.expr);
gen_fprintf(f, ") {\n");
- gen_statements(f, st->w.sts);
+ gen_statements(f, parent, st->w.sts);
gen_fprintf(f, "\t}\n");
return;
case STATEMENT_STRUCT:
- gen_struct(NULL, &st->s.data);
+ gen_struct(NULL, &st->s.data, NULL);
// XXX put st->s.data somewhere to create this proc.
gen_fprintf(f, "\toffset = dissect_struct_%s(tvb, pinfo, tree, hf_costam, offset);\n", st->s.data.tmpid);
return;
case STATEMENT_FIELD:
- {
- struct symbol *sym;
-
- if (!st->f.hfi) {
- st->f.hfi = hfi_add(&st->f);
- xassert(f == NULL);
- }
-
- sym = symbol_find(st->f.t_id, SYMBOL_STRUCT | SYMBOL_TYPE);
-
- if (!sym) {
- fprintf(stderr, "can't find: %s\n", st->f.t_id);
- abort();
- }
-
- symbol_add(st->f.id, SYMBOL_FIELD, &st->f);
-
- if (sym->type == SYMBOL_STRUCT)
- gen_field_struct(f, st, sym->data);
- else if (sym->type == SYMBOL_TYPE)
- gen_field_type(f, st, sym->data);
- else {
- /* XXX, SYMBOL_TABLE? */
- fprintf(stderr, "%s: wrong type [%d]\n", st->f.t_id, sym->type);
- abort();
- }
+ gen_statement_field(f, parent, &st->f, st->attr_list);
return;
- }
/* case STATEMENT_DYNAMIC_SWITCH: */
case STATEMENT_SWITCH:
@@ -1052,7 +1295,7 @@ gen_statement(FILE *f, npl_statement_t *st)
if (c->st) {
gen_fprintf(f, "\t\t");
- gen_statement(f, c->st);
+ gen_statement(f, parent, c->st);
gen_fprintf(f, "\t\t\tbreak;\n");
}
c = c->next;
@@ -1061,7 +1304,7 @@ gen_statement(FILE *f, npl_statement_t *st)
if (st->sw.data.default_st) {
gen_fprintf(f, "\t\tdefault:\n");
gen_fprintf(f, "\t\t");
- gen_statement(f, st->sw.data.default_st);
+ gen_statement(f, parent, st->sw.data.default_st);
}
gen_fprintf(f, "\t}\n");
@@ -1100,7 +1343,7 @@ gen_statement(FILE *f, npl_statement_t *st)
}
gen_fprintf(f, ") {\n");
gen_fprintf(f, "\t");
- gen_statement(f, case_st);
+ gen_statement(f, parent, case_st);
gen_fprintf(f, "\t} ");
if (c || default_st)
@@ -1110,13 +1353,13 @@ gen_statement(FILE *f, npl_statement_t *st)
if (default_st) {
gen_fprintf(f, "{\n");
gen_fprintf(f, "\t");
- gen_statement(f, default_st);
+ gen_statement(f, parent, default_st);
gen_fprintf(f, "\t}\n");
}
} else {
if (st->sw.data.default_st)
- gen_statement(f, st->sw.data.default_st);
+ gen_statement(f, parent, st->sw.data.default_st);
}
return;
}
@@ -1125,14 +1368,14 @@ gen_statement(FILE *f, npl_statement_t *st)
}
static void
-gen_statements(FILE *f, struct _npl_statements *sts)
+gen_statements(FILE *f, struct parent_info *parent, struct _npl_statements *sts)
{
struct symbol *symroot;
symroot = symbols_push();
while (sts) {
- gen_statement(f, &sts->st);
+ gen_statement(f, parent, &sts->st);
sts = sts->next;
}
@@ -1141,11 +1384,21 @@ gen_statements(FILE *f, struct _npl_statements *sts)
}
static void
-gen_protocol(FILE *f, npl_protocol_t *p)
+decl_protocol(npl_protocol_t *p)
{
+ if (!p->sym)
+ p->sym = symbol_add(p->id, SYMBOL_PROTO, p);
+}
+
+static void
+gen_protocol(FILE *f, npl_protocol_t *p, npl_attribute_list_t *attr_list)
+{
+ struct parent_info this;
+
+ p->sym->is_static = 1;
gen_fprintf(f,
"static int\n"
- "dissect_%s(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)\n", p->id);
+ "dissect_%s(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void *data _U_)\n", p->id);
gen_fprintf(f, "{\n");
gen_fprintf(f,
@@ -1155,12 +1408,43 @@ gen_protocol(FILE *f, npl_protocol_t *p)
"\n"
);
+ resolve_attr_list(attr_list);
+ while (attr_list) {
+ const char *attr_name = attr_list->resolved;
+ npl_expression_t *attr_expr = attr_list->assign_expr;
+ int flags = attr_list->flags;
+
+ if (attr_name) {
+ if (!strcasecmp(attr_name, "DataTypeByteOrder")) {
+ xassert(flags == 0);
+ xassert(attr_expr != NULL);
+
+ p->byte_order_attr = attr_expr;
+
+ } else
+ fprintf(stderr, "!!! generating protocol attr: %s not handled!\n", attr_name);
+ } else
+ fprintf(stderr, "!!! generating protocol attr: not resolved!\n");
+
+ attr_list = attr_list->next;
+ }
+
+ gen_fprintf(f,
+ "\tif (parent_tree) {\n"
+ "\t\tti = proto_tree_add_item(parent_tree, proto_%s, tvb, offset, -1, ENC_NA);\n"
+ "\t\ttree = proto_item_add_subtree(ti, ett_%s);\n"
+ "\t}\n", p->id, p->id);
+
if (p->format) {
}
- gen_statements(f, p->sts);
+ memset(&this, 0, sizeof(this));
+ this.id = p->id;
+ this.byte_order = p->byte_order_attr;
+
+ gen_statements(f, &this, p->sts);
gen_fprintf(f, "\tproto_item_set_len(ti, offset);\n");
gen_fprintf(f, "\treturn offset;\n");
@@ -1178,9 +1462,10 @@ decl_struct(npl_struct_t *s)
}
static void
-gen_struct(FILE *f, npl_struct_t *s)
+gen_struct(FILE *f, npl_struct_t *s, npl_attribute_list_t *attr_list)
{
const char *id = s->tmpid;
+ struct parent_info this;
if (!id)
id = s->tmpid = s->id;
@@ -1200,6 +1485,8 @@ gen_struct(FILE *f, npl_struct_t *s)
fprintf(stderr, "TODO: s->count_expr");
}
+ if (s->sym)
+ s->sym->is_static = 1;
gen_fprintf(f,
"static int\n"
"dissect_struct_%s(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int hf_index%s, int offset)\n"
@@ -1208,13 +1495,19 @@ gen_struct(FILE *f, npl_struct_t *s)
if (!s->private) {
gen_fprintf(f, "\tconst int org_offset = offset;\n");
- gen_fprintf(f, "\tproto_tree *tree = NULL\n");
+ gen_fprintf(f, "\tproto_tree *tree = NULL;\n");
gen_fprintf(f, "\tproto_item *ti = NULL;\n");
} else
- gen_fprintf(f, "\tproto_tree *tree = parent_tree\n");
+ gen_fprintf(f, "\tproto_tree *tree = parent_tree;\n");
gen_fprintf(f,"\n");
+ resolve_attr_list(attr_list);
+ while (attr_list) {
+ /* XXX, attr */
+ attr_list = attr_list->next;
+ }
+
if (!s->private) {
/*
if (s->format) {
@@ -1228,16 +1521,19 @@ gen_struct(FILE *f, npl_struct_t *s)
gen_fprintf(f,
"\tif (parent_tree) {\n"
- "\t\tti = proto_tree_add_bytes_format(parent_tree, hf_index, tvb, offset, 0, NULL, \"%s\");\n"
+ "\t\tti = proto_tree_add_bytes_format_value(parent_tree, hf_index, tvb, offset, 0, NULL, \"%s\");\n"
"\t\ttree = proto_item_add_subtree(ti, %s);\n"
- "\t}\n", "description", ett_var(s->ett));
+ "\t}\n", "", ett_var(s->ett));
} else {
if (s->format)
fprintf(stderr, "s->private && s->format?\n");
}
- gen_statements(f, s->sts);
+ memset(&this, 0, sizeof(this));
+ this.id = s->id;
+
+ gen_statements(f, &this, s->sts);
if (!s->private)
gen_fprintf(f, "\tproto_item_set_len(ti, offset - org_offset);\n");
@@ -1271,49 +1567,42 @@ decl_type(npl_type_t *t)
}
static void
-gen_attr(FILE *f, npl_attr_t *a)
-{
- fprintf(stderr, "gen_attr() TODO\n");
-}
-
-static void
walk_decl(FILE *f, npl_decl_t *d, int full_run)
{
switch (d->type) {
- case DECL_ATTR:
- if (!full_run)
- return;
- gen_attr(f, &d->a.data);
- return;
case DECL_STRUCT:
decl_struct(&d->s.data);
if (!full_run)
return;
- gen_struct(f, &d->s.data);
+ gen_struct(f, &d->s.data, d->attr_list);
return;
case DECL_TABLE:
+ xassert(d->attr_list == NULL);
decl_table(&d->t.data);
if (!full_run)
return;
gen_table(f, &d->t.data);
return;
case DECL_PROTOCOL:
- /* XXX decl_protocol */
+ decl_protocol(&d->p.data);
if (!full_run)
return;
- gen_protocol(f, &d->p.data);
+ gen_protocol(f, &d->p.data, d->attr_list);
return;
case DECL_CONST:
+ xassert(d->attr_list == NULL);
decl_const(&d->c.data);
if (!full_run)
return;
return;
case DECL_TYPE:
+ xassert(d->attr_list == NULL);
decl_type(&d->ty.data);
if (!full_run)
return;
return;
case DECL_INCLUDE:
+ xassert(d->attr_list == NULL);
/* done in parse_includes() */
return;
}
@@ -1398,8 +1687,8 @@ gen_proto_register(FILE *f, const char *proto_name)
for (hfi = hfs; hfi; hfi = hfi->next) {
gen_fprintf(f,
"\t\t{ &%s,\n"
- "\t\t\t{ \"%s\", \"%s\", %s, %s, NULL, 0x%.2x, NULL, HFILL }\n"
- "\t\t},\n", hfi_var(hfi), hfi_name(hfi), hfi_filter(hfi), hfi_type(hfi), hfi_display(hfi), hfi_mask(hfi) );
+ "\t\t\t{ \"%s\", \"%s.%s\", %s, %s, NULL, 0x%.2x, NULL, HFILL }\n"
+ "\t\t},\n", hfi_var(hfi), hfi_name(hfi), proto_name, hfi_filter(hfi), hfi_type(hfi), hfi_display(hfi), hfi_mask(hfi) );
}
gen_fprintf(f, "\t};\n\n");
@@ -1410,12 +1699,12 @@ gen_proto_register(FILE *f, const char *proto_name)
gen_fprintf(f, "\t};\n\n");
- gen_fprintf(f, "\tproto_%s = proto_register_protocol(\"foo1\", \"foo2\", \"%s\");\n\n", proto_name, proto_name);
+ gen_fprintf(f, "\tproto_%s = proto_register_protocol(\"%s\", \"%s\", \"%s\");\n\n", proto_name, proto_name, proto_name, proto_name);
gen_fprintf(f, "\tproto_register_field_array(proto_%s, hf, array_length(hf));\n", proto_name);
gen_fprintf(f, "\tproto_register_subtree_array(ett, array_length(ett));\n");
- gen_fprintf(f, "}\n");
+ gen_fprintf(f, "}\n\n");
}
static void
@@ -1433,7 +1722,7 @@ gen_proto_handoff(FILE *f, const char *proto_name)
xml_handle = find_dissector("xml");
#endif
- gen_fprintf(f, "}\n");
+ gen_fprintf(f, "}\n\n");
}
static const npl_protocol_t *
@@ -1484,6 +1773,7 @@ int main(int argc, char **argv) {
if (!(f = fopen(argv[i], "rb"))) {
fprintf(stderr, "can't open: %s\n", argv[i]);
+ continue;
return 1;
}
@@ -1499,10 +1789,12 @@ int main(int argc, char **argv) {
merge_code(&code, &mcode);
}
+#if 1
{
const npl_protocol_t *proto = get_protocol(&code);
const char *proto_name = (proto) ? proto->id : "noname";
FILE *out;
+ struct symbol *sym;
parse_includes(&code);
walk_code(NULL, &code, 1);
@@ -1515,9 +1807,30 @@ int main(int argc, char **argv) {
gen_fprintf(out, "#include <epan/packet.h>\n");
gen_fprintf(out, "\n");
- /* TODO declare forward */
+ /* declare forward (or extern) */
+ /* XXX, not enough to generate from table (like private structs) */
+ for (sym = symbols; sym; sym = sym->next) {
+ const char *sstatic = (sym->is_static) ? "static " : "";
+
+ if (!sym->is_used)
+ continue;
+
+ switch (sym->type) {
+ case SYMBOL_TABLE:
+ gen_fprintf(out, "%sconst char *format_table_%s(...)\n", sstatic, sym->id);
+ break;
+ case SYMBOL_STRUCT:
+ gen_fprintf(out, "%sint dissect_struct_%s(tvbuff_t *, packet_info *, proto_tree *, int, int);\n", sstatic, sym->id);
+ break;
+ case SYMBOL_PROTO:
+ gen_fprintf(out, "%sint dissect_%s(tvbuff_t *, packet_info *, proto_tree *, void *);\n", sstatic, sym->id);
+ break;
+ }
+ }
+ gen_fprintf(out, "\n");
gen_fprintf(out, "static int proto_%s = -1;\n", proto_name);
+ gen_fprintf(out, "static int ett_%s = -1;\n", proto_name);
gen_vars(out);
walk_code(out, &code, 1);
@@ -1527,6 +1840,7 @@ int main(int argc, char **argv) {
fclose(out);
}
+#endif
return 0;
}
diff --git a/tools/npl/parser.l b/tools/npl/parser.l
index 57e0d5763d..95fa159e97 100644
--- a/tools/npl/parser.l
+++ b/tools/npl/parser.l
@@ -33,7 +33,7 @@
%{
#define YY_DECL static token_type_t yylex(void)
-#include <stdarg.h>
+#include <setjmp.h>
#include "ast.h"
#include "xmem.h"
@@ -305,6 +305,10 @@ static const char *token_name(token_type_t tok) {
return buf;
}
+static jmp_buf parser_exception;
+
+static void xfail(void) { longjmp(parser_exception, 1); }
+
static void next_token(void) { token = yylex(); }
static inline int is_token(token_type_t tok) { return (token == tok); }
@@ -316,14 +320,14 @@ static void _strange(int line) {
static void _nomatch(int line) {
fprintf(stdout, "!!!! %s:%d got: %d (%s) @%s:%d\n", __FILE__, line, token, yytext, yyfilename, yylineno);
- abort();
+ xfail();
}
#define nomatch() _nomatch(__LINE__)
static void _accept(token_type_t tok, int line) {
if (tok != token) {
fprintf(stdout, "%s:%d got: %d (%s) expected %s @%s:%d\n", __FILE__, line, token, yytext, token_name(tok), yyfilename, yylineno);
- abort();
+ xfail();
}
next_token();
}
@@ -349,7 +353,7 @@ static char *_accept_id(int line) {
if (!is_id()) {
fprintf(stdout, "%s:%d got: %d (%s) expected %s @%s:%d\n", __FILE__, line, token, yytext, token_name(TOKEN_ID), yyfilename, yylineno);
- abort();
+ xfail();
}
id = xstrdup(yytext);
@@ -365,7 +369,7 @@ static unsigned int _accept_int(int line) {
if (token != TOKEN_DIGIT) {
fprintf(stdout, "%s:%d got: %d (%s) expected %s @%s:%d\n", __FILE__, line, token, yytext, token_name(TOKEN_DIGIT), yyfilename, yylineno);
- abort();
+ xfail();
}
if (yytext[0] == '0' && yytext[1] == 'x')
@@ -387,13 +391,13 @@ static char *_accept_str(int line) {
if (token != TOKEN_STR) {
fprintf(stdout, "%s:%d got: %d (%s) expected %s @%s:%d\n", __FILE__, line, token, yytext, token_name(TOKEN_STR), yyfilename, yylineno);
- abort();
+ xfail();
}
len = strlen(yytext);
if (len < 2 || yytext[0] != '"' || yytext[len-1] != '"')
- abort();
+ xfail();
#if 0
char *ptr;
size_t i;
@@ -434,7 +438,7 @@ static char *_accept_str(int line) {
break;
default:
- fprintf(stderr, "unrecog: %c @ %d\n", yytext[i], yylineno);
+ fprintf(stdout, "unrecog: %c @ %d\n", yytext[i], yylineno);
*ptr++ = yytext[i];
}
@@ -474,8 +478,10 @@ parse_params(npl_params_t *p)
accept(TOKEN_LPAREN);
do {
- if (i == NPL_PARAMS_MAX)
- abort();
+ if (i == NPL_PARAMS_MAX) {
+ fprintf(stdout, "i == NPL_PARAMS_MAX");
+ xfail();
+ }
p->args[i++] = accept_id();
@@ -506,14 +512,14 @@ parse_primary(npl_expression_t *expr)
if (is_token(TOKEN_FLOAT)) {
// XXX ast
accept(TOKEN_FLOAT);
- expr->type = 0;
+ expr->type = -1;
return;
}
if (is_token(TOKEN_CHAR)) {
// XXX ast
accept(TOKEN_CHAR);
- expr->type = 0;
+ expr->type = -2;
return;
}
@@ -929,15 +935,13 @@ parse_expression(npl_expression_t *expr)
static int is_attribute(void) { return is_token(TOKEN_LBRACKET); }
-static void
-parse_attributes(npl_attr_t *attr)
+static npl_attribute_list_t **
+pparse_attributes(npl_attribute_list_t **ptr)
{
- npl_expression_list_t **ptr = &attr->expr_list;
-
accept(TOKEN_LBRACKET);
do {
- npl_expression_list_t *cur = xnew(npl_expression_list_t);
+ npl_attribute_list_t *cur = xnew(npl_attribute_list_t);
*ptr = cur;
ptr = &(cur->next);
@@ -952,7 +956,15 @@ parse_attributes(npl_attr_t *attr)
// while (is_token_accept(TOKEN_COMMA));
accept(TOKEN_RBRACKET);
- *ptr = NULL;
+ return ptr;
+}
+
+static void
+parse_all_attributes(npl_attribute_list_t **attr_ptr)
+{
+ while (is_attribute())
+ attr_ptr = pparse_attributes(attr_ptr);
+ *attr_ptr = NULL;
}
static void parse_statement(npl_statement_t *st);
@@ -1097,11 +1109,7 @@ static void parse_struct(npl_struct_t *s, int statement);
static void
parse_statement(npl_statement_t *st)
{
- while (is_attribute()) {
- // XXX ast
- npl_attr_t a = { };
- parse_attributes(&a);
- }
+ parse_all_attributes(&st->attr_list);
if (is_token(TOKEN_WHILE)) {
parse_while(st);
@@ -1135,6 +1143,7 @@ parse_statement(npl_statement_t *st)
#if 1
if (is_token(TOKEN_SEMICOLON)) {
accept(TOKEN_SEMICOLON);
+ st->type = -3;
return;
}
#endif
@@ -1330,7 +1339,7 @@ parse_type(npl_type_t *t)
nomatch();
#if 0
if (*ptr)
- fprintf(stderr, "already got %s attr!\n", str);
+ fprintf(stdout, "already got %s attr!\n", str);
#endif
accept(TOKEN_ASSIGN);
*ptr = xparse_expression();
@@ -1366,11 +1375,9 @@ parse_const(npl_const_t *c)
static void
parse_decl(npl_decl_t *d)
{
- if (is_token(TOKEN_LBRACKET)) {
- d->type = DECL_ATTR;
- parse_attributes(&d->a.data);
+ parse_all_attributes(&d->attr_list);
- } else if (is_token(TOKEN_STRUCT)) {
+ if (is_token(TOKEN_STRUCT)) {
d->type = DECL_STRUCT;
parse_struct(&d->s.data, 0);
@@ -1418,16 +1425,19 @@ parse_npl(npl_code_t *code)
int
npl_parse_file(npl_code_t *code, FILE *f, const char *filename)
{
- int parse_ok = 0;
+ volatile int parse_ok = 0;
+
yyfilename = filename;
yyin = f;
- next_token();
- parse_npl(code);
- parse_ok = 1;
+ if (!setjmp(parser_exception)) {
+ next_token();
+ parse_npl(code);
+ parse_ok = 1;
+ }
yylex_destroy();
- return parse_ok;
+ return (parse_ok == 1);
}