diff options
author | Gerald Combs <gerald@wireshark.org> | 2022-01-25 13:46:50 -0800 |
---|---|---|
committer | Jaap Keuter <jaap.keuter@xs4all.nl> | 2022-01-26 17:35:58 +0000 |
commit | 6e48f973ec30ad8bf6d4a090d2493dff8f27a9a3 (patch) | |
tree | 3561043aba5f1dc485ad2154203086f7c8f9ff95 /tools/npl/npl.c | |
parent | 36521f27b384b13cc1359c5c16d10e3ed1094b60 (diff) |
Tools: Remove NPL.
Remove tools/npl. It doesn't appear to be used and hasn't had any
activity for many years. Ping #17897.
Diffstat (limited to 'tools/npl/npl.c')
-rw-r--r-- | tools/npl/npl.c | 1993 |
1 files changed, 0 insertions, 1993 deletions
diff --git a/tools/npl/npl.c b/tools/npl/npl.c deleted file mode 100644 index a929fca127..0000000000 --- a/tools/npl/npl.c +++ /dev/null @@ -1,1993 +0,0 @@ -/* - * Copyright 2012-2013, Jakub Zawadzki <darkjames-ws@darkjames.pl> - * - * SPDX-License-Identifier: GPL-2.0-or-later - */ - -#include <stdio.h> -#include <ctype.h> -#include <string.h> -#include <stdlib.h> - -#include "ast.h" -#include "xmem.h" - -int npl_parse_file(npl_code_t *code, FILE *f, const char *filename); /* parser.l */ - -struct ettinfo { - struct ettinfo *next; - npl_struct_t *st; -}; - -struct hfinfo { - struct hfinfo *next; - struct _npl_statement_field *st; - const char *parent; - - const char *hf_type; -}; - -enum symbol_type { - SYMBOL_ANY = (~0), - SYMBOL_EXPR = (1 << 0), - SYMBOL_STRUCT = (1 << 1), - SYMBOL_TABLE = (1 << 2), - SYMBOL_TYPE = (1 << 3), - SYMBOL_FIELD = (1 << 4), - - 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; - int is_static:1; - int is_used:1; -}; - -struct parent_info { - const char *id; - npl_expression_t *byte_order; - - int cur_offset; - /* 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); - -static struct symbol *symbols; -static struct hfinfo *hfs; -static struct ettinfo *etts; - -static npl_expression_t format_string_e; -static npl_expression_t is_value_none_e; -static npl_expression_t this_e; - -static npl_expression_t property_e; -static npl_expression_t global_e; -static npl_expression_t local_e; - -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 int symbols_lvl = 0; - -static struct symbol * -symbols_push(void) -{ - symbols_lvl++; - - return symbols; -} - -static void -symbols_pop(struct symbol *sym) -{ - --symbols_lvl; - - while (symbols != sym) { - struct symbol *s = symbols; - - symbols = symbols->next; - free(s); - } -} - -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 (sym->hash == hash && !strcasecmp(sym->id, id)) { - // XXX, check type - return sym; - } - } - return NULL; -} - -static struct symbol * -symbol_add(const char *id, enum symbol_type type, void *data) -{ - struct symbol *sym; - - sym = symbol_find(id, SYMBOL_ANY); - if (sym) { - if (sym->lvl == symbols_lvl) { - fprintf(stderr, "Error: symbol %s already added [type: %d]\n", id, sym->type); - abort(); - } else - fprintf(stderr, "Warning: symbol %s shadow another symbol [type: %d]\n", id, sym->type); - } - - sym = xnew(struct symbol); - - sym->id = id; - sym->hash = symbol_hash(id); - sym->type = type; - sym->lvl = symbols_lvl; - sym->data = data; - - sym->next = symbols; - symbols = sym; - - return sym; -} - -static struct ettinfo * -ett_add(npl_struct_t *st) -{ - struct ettinfo *new = xnew(struct ettinfo); - - new->st = st; - - new->next = etts; - etts = new; - - return new; -} - -static const char * -ett_var(const struct ettinfo *ett) -{ - static char ett_name[256]; - - snprintf(ett_name, sizeof(ett_name), "ett_%s", ett->st->id); - - return ett_name; -} - -static struct hfinfo * -hfi_add(struct _npl_statement_field *st, const struct parent_info *parent) -{ - struct hfinfo *new = xnew(struct hfinfo); - - new->st = st; - new->parent = parent->id; - - new->next = hfs; - hfs = new; - - 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) -{ - static char hf_name[256]; - size_t pos; - - pos = snprintf(hf_name, sizeof(hf_name), "hf_field_"); - xassert(pos < sizeof(hf_name)); - - 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; -} - -static const char * -hfi_name(const struct hfinfo *hfi) -{ - return hfi->st->id; -} - -static const char * -hfi_filter(const struct hfinfo *hfi) -{ - 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 * -hfi_type(const struct hfinfo *hfi) -{ - if (hfi->hf_type) - return hfi->hf_type; - /* 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 -count_expression_list(const npl_expression_list_t *exprs) -{ - int c = 0; - - while (exprs) { - c++; - exprs = exprs->next; - } - return c; -} - -static struct symbol * -expr_to_symbol(const npl_expression_t *e) -{ - struct symbol *sym = NULL; - - if (e->type == EXPRESSION_ID) { - 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); - - if (new_sym) - sym = new_sym; - } - } - return sym; -} - -static int -expr_to_const_int(const npl_expression_t *e, int *val) -{ - struct symbol *sym; - - if (e->type == EXPRESSION_INT) { - *val = e->num.digit; - return 1; - } - if (e->type == EXPRESSION_UNARY) { - if (!expr_to_const_int(e->u.operand, val)) - return 0; - - switch (e->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; - } - - sym = expr_to_symbol(e); - if (sym && sym->type == SYMBOL_EXPR) - return expr_to_const_int(sym->data, val); - - return 0; -} - -static int -expr_to_const_str(const npl_expression_t *e, const char **val) -{ - struct symbol *sym; - - if (e->type == EXPRESSION_STR) { - *val = e->str.str; - return 1; - } - - sym = expr_to_symbol(e); - if (sym && sym->type == SYMBOL_EXPR) - return expr_to_const_str(sym->data, val); - - return 0; -} - -static const char * -type_to_ctype(const npl_type_t *t, int size) -{ - switch (t->type) { - case FIELD_DECIMAL: - if (size == 4) - return "float"; - if (size == 8) - return "double"; - - fprintf(stderr, "!!! decimal, size: %d\n", size); - return NULL; - - case FIELD_NUMBER: - if (size == 1) - return "gint8"; - if (size == 2) - return "gint16"; - if (size == 3 || size == 4) - return "gint32"; - if (size > 4 && size <= 8) - return "gint64"; - - fprintf(stderr, "!!! number, size: %d\n", size); - return NULL; - - case FIELD_UNSIGNED_NUMBER: - if (size == 1) - return "guint8"; - if (size == 2) - return "guint16"; - if (size == 3 || size == 4) - return "guint32"; - if (size > 4 && size <= 8) - return "guint64"; - - fprintf(stderr, "!!! number, size: %d\n", size); - return NULL; - - case FIELD_TIME: - return "nstime_t"; - } - fprintf(stderr, "!!! not handled, type: %d, size: %d\n", t->type, 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 == NPL_ENDIAN_LE) - return "tvb_get_letohieee_float"; - if (size == 4 && endian == NPL_ENDIAN_BE) - return "tvb_get_ntohieee_float"; - - if (size == 8 && endian == NPL_ENDIAN_LE) - return "tvb_get_letohieee_double"; - if (size == 8 && endian == NPL_ENDIAN_BE) - return "tvb_get_ntohieee_double"; - - fprintf(stderr, "!!! decimal, size: %d, endian: %d\n", size, endian); - return NULL; - - case FIELD_UNSIGNED_NUMBER: - case FIELD_NUMBER: - if (size == 1) - return "tvb_get_guint8"; - - if (size == 2 && endian == NPL_ENDIAN_LE) - return "tvb_get_letohs"; - if (size == 2 && endian == NPL_ENDIAN_BE) - return "tvb_get_ntohs"; - - 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 == NPL_ENDIAN_BE) - return "tvb_get_ntoh24"; - - if (size == 4 && endian == NPL_ENDIAN_LE) - return "tvb_get_letohl"; - if (size == 4 && endian == NPL_ENDIAN_BE) - return "tvb_get_ntohl"; - - fprintf(stderr, "!!! number, size: %d, endian: %d\n", size, endian); - return NULL; - } - fprintf(stderr, "!!! not handled, type: %d, size: %d, endian: %d\n", t->type, size, endian); - return NULL; -} - -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 > 4 && 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 > 4 && 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 { \ - if (f) fprintf(f, args); \ - } while (0) - -static const char * -op1_to_str(npl_op1_t op) -{ - switch (op) { - case OP1_MINUS: - return "-"; - case OP1_NOT: - return "!"; - case OP1_NEG: - return "~"; - } - fprintf(stderr, "XXX op: %d\n", op); - return ""; -} - -static const char * -op2_to_str(npl_op2_t op) -{ - switch (op) { - case OP2_PLUS: - return "+"; - case OP2_MINUS: - return "-"; - case OP2_SHL: - return "<<"; - case OP2_SHR: - return ">>"; - case OP2_EQUAL: - return "=="; - case OP2_NOTEQUAL: - return "!="; - case OP2_LOGIC_OR: - return "||"; - case OP2_LOGIC_AND: - return "&&"; - case OP2_OR: - return "|"; - case OP2_XOR: - return "^"; - case OP2_AND: - return "&"; - case OP2_GREATER: - return ">"; - case OP2_GEQUAL: - return ">="; - case OP2_LESS: - return "<"; - case OP2_LEQUAL: - return "<="; - } - fprintf(stderr, "XXX op: %d\n", op); - return ""; -} - -enum attr_flag { - ATTR_PROPERTY = 0, - - ATTR_GLOBAL = 1 << 0, - ATTR_LOCAL = 1 << 1, - - ATTR_CONV = 1 << 5, - - ATTR_POST = 1 << 10 -}; - -static enum attr_flag -resolve_attr_id(const char *id) -{ - if (!strcasecmp(id, "property")) - return ATTR_PROPERTY; - if (!strcasecmp(id, "Global")) - return ATTR_GLOBAL; - if (!strcasecmp(id, "local")) - return ATTR_LOCAL; - if (!strcasecmp(id, "conversation")) - return ATTR_CONV; - if (!strcasecmp(id, "post")) - return ATTR_POST; - - fprintf(stderr, ":: attr-id: %s\n", id); - abort(); - return -1; -} - -static int -resolve_attr_expr(const struct _npl_expression *expr) -{ - int flags = 0; - - switch (expr->type) { - case EXPRESSION_ID: - flags |= (int) resolve_attr_id(expr->id.id); - break; - - case EXPRESSION_FIELD: - flags |= resolve_attr_expr(expr->fld.base); - flags |= (int) resolve_attr_id(expr->fld.field); - break; - - default: - fprintf(stderr, "resolve_attr_expr() %d\n", expr->type); - break; - } - - xassert(!((flags & ATTR_GLOBAL) && (flags & ATTR_LOCAL))); - - return flags; -} - -static void -resolve_attr_list(npl_attribute_list_t *attr) -{ - while (attr) { - struct _npl_expression *expr; - 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(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) -{ - xassert(field->generate_var || f == NULL); - - field->generate_var = 1; - gen_fprintf(f, "_field_%s", field->id); -} - -static void -gen_expr_type(FILE *f, npl_type_t *t) -{ - int size = -1; - int byte_order = -1; - const char *fetch_func; - - if (t->size && !expr_to_const_int(t->size, &size)) - fprintf(stderr, "!!! expr_to_const_int(size) failed for type: %s\n", t->id); - - 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); - - fetch_func = type_to_tvb(t, size, byte_order); - if (fetch_func) - gen_fprintf(f, "%s", fetch_func); - else - gen_fprintf(f, "<<TYPE %s>>", t->id); -} - -static void -gen_expr_table(FILE *f, npl_table_t *t) -{ - gen_fprintf(f, " format_table_%s ", t->id); -} - -static struct symbol * -gen_expr(FILE *f, npl_expression_t *e) -{ - switch (e->type) { - case EXPRESSION_ID: - { - struct symbol *sym = symbol_find(e->id.id, SYMBOL_EXPR | SYMBOL_FIELD | SYMBOL_TYPE | SYMBOL_SIMPLE | SYMBOL_TABLE); - - if (!sym) { - 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); - - else if (sym->type == SYMBOL_FIELD) - gen_expr_field(f, sym->data); - - else if (sym->type == SYMBOL_TYPE) - gen_expr_type(f, sym->data); - - else if (sym->type == SYMBOL_TABLE) - gen_expr_table(f, sym->data); - - else if (sym->type == SYMBOL_SIMPLE) - gen_fprintf(f, "%s", (const char *) sym->data); - - else { - fprintf(stderr, "ID %s wrong type [%d]\n", sym->id, sym->type); - abort(); - } - return sym; - } - - case EXPRESSION_INT: - gen_fprintf(f, " %d ", e->num.digit); - return NULL; - - case EXPRESSION_STR: - // XXX e->str.str is escaped, almost like C-string so just print it. - gen_fprintf(f, " \"%s\" ", e->str.str); - return NULL; - - case EXPRESSION_UNARY: - gen_fprintf(f, "("); - gen_fprintf(f, "%s", op1_to_str(e->u.operator)); - gen_expr(f, e->u.operand); - gen_fprintf(f, ")"); - return NULL; - - case EXPRESSION_BINARY: - gen_fprintf(f, "("); - gen_expr(f, e->b.operand1); - gen_fprintf(f, " %s ", op2_to_str(e->b.operator)); - gen_expr(f, e->b.operand2); - gen_fprintf(f, ")"); - return NULL; - - case EXPRESSION_CALL: - { - npl_expression_list_t *arg; - struct symbol *sym; - const char *ind = ""; - - sym = gen_expr(NULL, e->call.fn); - if (!sym) { - fprintf(stderr, "can't call no-symbol\n"); - abort(); - } - /* XXX check if sym->type can be called (function) */ - - - gen_expr(f, e->call.fn); - gen_fprintf(f, "("); - for (arg = e->call.args; arg; arg = arg->next) { - gen_fprintf(f, "%s", ind); - gen_expr(f, arg->expr); - ind = ", "; - } - gen_fprintf(f, ")"); - return NULL; - } - - case EXPRESSION_COND: - gen_fprintf(f, "(("); - gen_expr(f, e->c.test_expr); - gen_fprintf(f, ") ? "); - gen_expr(f, e->c.true_expr); - gen_fprintf(f, " : "); - gen_expr(f, e->c.false_expr); - gen_fprintf(f, ")"); - return NULL; - - case EXPRESSION_FIELD: - { - struct symbol *sym; - - sym = gen_expr(NULL, e->fld.base); - if (!sym) { - fprintf(stderr, "can't field no-symbol (accessing %s)\n", e->fld.field); - abort(); - } - /* XXX check if sym->type can be dereferenced (struct) */ - - if (sym->data == &property_e) { - gen_fprintf(f, "<< PROPERTY %s>>", e->fld.field); - } else if (sym->data == &local_e) { - gen_fprintf(f, "_local_property_%s", e->fld.field); - } else if (sym->data == &global_e) { - gen_fprintf(f, "<< GLOBAL PROPERTY %s>>", e->fld.field); - } else { - gen_expr(f, e->fld.base); - gen_fprintf(f, ".%s ", e->fld.field); - } - return NULL; - } - } - - if (e == &this_e) - gen_fprintf(f, "<< this >>"); - else if (e == &format_string_e) - gen_fprintf(f, "<< FORMAT STRING >>"); - else if (e == &is_value_none_e) - gen_fprintf(f, "<< IS VALUE NONE >>"); - - else if (e == &property_e || e == &global_e || e == &local_e) - { /* silent expr->type: 0 warnings */ } - else - fprintf(stderr, "XXX expr->type: %d\n", e->type); - - return NULL; -} - -enum table_struct { TABLE_FULL, TABLE_VALUE_STRING, TABLE_STRING_STRING }; - -static enum table_struct -gen_table_struct(FILE *f, npl_table_t *t) -{ - struct npl_table_case *c; - - int all_int = 1; - int all_str = 1; - - if (t->params.count > 1 || !t->switch_expr) - return TABLE_FULL; - - for (c = t->cases; c; c = c->next) { - const char *str; - int val; - - if (!c->return_expr || !expr_to_const_str(c->return_expr, &str)) - return 0; - - if (all_int && !expr_to_const_int(&c->e, &val)) - all_int = 0; - if (all_str && !expr_to_const_str(&c->e, &str)) - all_str = 0; - - if (!all_int && !all_str) - return TABLE_FULL; - } - - /* table can be converted to value_string, generate one */ - if (all_int) { - gen_fprintf(f, - "static const value_string %s_vals[] = {\n", - t->id); - - if (f) - for (c = t->cases; c; c = c->next) { - const char *str; - int val; - - /* checked above, should not fail now */ - if (!expr_to_const_str(c->return_expr, &str)) - fail("expr_to_const_str(str)"); - if (!expr_to_const_int(&c->e, &val)) - fail("expr_to_const_int(val)"); - - gen_fprintf(f, "\t{ 0x%x, \"%s\" },\n", val, str); - } - gen_fprintf(f, "\t{ 0, NULL }\n"); - gen_fprintf(f, "};\n"); - return TABLE_VALUE_STRING; - } - - /* table can be converted to string_string, generate one */ - if (all_str) { - gen_fprintf(f, - "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; - - /* checked above, should not fail now */ - if (!expr_to_const_str(c->return_expr, &str)) - fail("expr_to_const_str(str)"); - if (!expr_to_const_str(&c->e, &val)) - fail("expr_to_const_str(val)"); - - gen_fprintf(f, "\t{ \"%s\", \"%s\" },\n", val, str); - } - gen_fprintf(f, "\t{ NULL, NULL }\n"); - gen_fprintf(f, "};\n"); - return TABLE_STRING_STRING; - } - - return TABLE_FULL; -} - -static void -gen_table_func(FILE *f, npl_table_t *t) -{ - struct npl_table_case *c; - - if (t->switch_expr) { - gen_fprintf(f, "\tswitch ("); - gen_expr(f, t->switch_expr); - gen_fprintf(f, ") {\n"); - - for (c = t->cases; c; c = c->next) { -again1: - gen_fprintf(f, "\t\tcase "); - gen_expr(f, &c->e); - gen_fprintf(f, ": "); - - if (!c->return_expr) { - c = c->next; - xassert(c != NULL); - gen_fprintf(f, "\n"); - goto again1; - } else { - gen_fprintf(f, "\n"); - gen_fprintf(f, "\t\t\treturn "); - gen_expr(f, c->return_expr); - gen_fprintf(f, ";\n"); - } - } - - gen_fprintf(f, "\t}\n"); - } else { - for (c = t->cases; c; c = c->next) { - - if (c == t->cases) - gen_fprintf(f, "\tif ("); - else - gen_fprintf(f, "\telse if ("); - -again2: - gen_fprintf(f, "("); - gen_expr(f, &c->e); - gen_fprintf(f, ")"); - - if (!c->return_expr) { - gen_fprintf(f, " || "); - c = c->next; - xassert(c != NULL); - goto again2; - } else { - gen_fprintf(f, ")\n"); - - gen_fprintf(f, "\t\treturn "); - gen_expr(f, c->return_expr); - gen_fprintf(f, ";\n"); - } - } - } -} - -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 "); - gen_expr(f, t->default_expr); - gen_fprintf(f, ";\n"); - } else - gen_fprintf(f, "\treturn \"\";\n"); - - gen_fprintf(f, "}\n\n"); - - symbols_pop(symroot); -} - -static void -gen_field_proto(FILE *f, struct _npl_statement_field *field, npl_protocol_t *p) -{ - /* XXX */ - gen_fprintf(f, "\t << CALL PROTOCOL %s >>\n", p->id); - /* XXX, do we care? (only when not @ tail?) */ - field->field_size = -1; -} - -static void -gen_field_struct(FILE *f, struct _npl_statement_field *field, npl_struct_t *s) -{ - // XXX st->f.bits, st->f.arr, st->f.format, st->f.sts - // XXX, st->f.generate_var - - gen_fprintf(f, "\toffset = dissect_struct_%s(tvb, pinfo, tree, %s, offset);\n", s->tmpid, hfi_var(field->hfi)); - - field->hfi->hf_type = "FT_BYTES"; - field->field_size = -1; -} - -static void -gen_field_size(FILE *f, struct symbol *sym_size, int size) -{ - 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, ") "); - - } else if (sym_size->type == SYMBOL_SIMPLE) { - gen_fprintf(f, "%s ", (const char *) sym_size->data); - - } 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, struct _npl_statement_field *field, npl_type_t *t) -{ - struct symbol *symroot; - int i; - - // XXX field.bits, field.arr, field.sts - - int size = -1; - struct symbol *size_sym = NULL; - - int byte_order = -1; - 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 = field->params; - int argc = count_expression_list(argv); - - if (t->params.count != argc) { - fprintf(stderr, "%s: number of params != number of argc (%d != %d)\n", t->id, t->params.count, argc); - abort(); - } - - symroot = symbols_push(); - - for (i = 0; i < argc; i++) { - symbol_add(t->params.args[i], SYMBOL_EXPR, argv->expr); - argv = argv->next; - } - - xassert(t->size != NULL); - if (!expr_to_const_int(t->size, &size)) { - size_sym = expr_to_symbol(t->size); - - if (!size_sym) { - fprintf(stderr, "!!! expr_to_const_int, _symbol(size) failed for type: %s\n", t->id); - abort(); - } - } - - 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 (field->format) - display_format = field->format; - else - display_format = t->display_format; - - 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 (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); - -/* - if (!ctype || !fetch_func) - abort(); -*/ - - /* XXX, we should declare variable on begin of block (< C99) */ - gen_fprintf(f, "\t%s _field_%s = %s(tvb, offset);\n", ctype, field->id, fetch_func); - } - - if (size_sym) { - if (size_sym->type == SYMBOL_FIELD) { - struct _npl_statement_field *sym_field = size_sym->data; - - xassert(sym_field->generate_var || f == NULL); - - sym_field->generate_var = 1; - } else - fprintf(stderr, "::: %s (%d)\n", size_sym->id, size_sym->type); - - hf_type = NULL; - - } else - hf_type = type_to_ft(t, size); - - field->hfi->hf_type = hf_type; - field->field_size = size; - - /* XXX, when generate_var we can use fetched value, not proto_tree_add_item() */ - -#if 0 - if (display_format) - fprintf(stderr, "XXX, format\n"); - else -#endif - 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"); - - gen_fprintf(f, "\toffset += "); - gen_field_size(f, size_sym, size); - gen_fprintf(f, ";\n"); - - symbols_pop(symroot); -} - -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; - const char *property_name = NULL; - int property_flags = 0; - - sym = symbol_find(field->t_id, SYMBOL_STRUCT | SYMBOL_PROTO | SYMBOL_TYPE); - if (!sym) { - fprintf(stderr, "can't find: %s\n", field->t_id); - abort(); - } - sym->is_used = 1; - - if (!field->hfi && sym->type != SYMBOL_PROTO) { - field->hfi = hfi_add(field, parent); - xassert(f == NULL); - } - - 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 attr_flags = attr_list->flags; - - if (attr_name) { - if (!strcasecmp(attr_name, "DataFieldByteOrder")) { - xassert(attr_flags == 0); - xassert(attr_expr != NULL); - - field->byte_order_attr = attr_expr; - - } else if (attr_expr) { - if (attr_flags & ATTR_LOCAL) { - /* XXX, declare only when first use. support < C99 */ - gen_fprintf(f, "\tTYPE _local_property_%s = ", attr_name); - gen_expr(f, attr_expr); - gen_fprintf(f, ";\n"); - } else { - gen_fprintf(f, "<<PROPERTY(%d) %s = ", attr_flags, attr_name); - gen_expr(f, attr_expr); - gen_fprintf(f, ">>\n"); - } - - } else { - /* only one for now */ - xassert(property_name == NULL); - - property_name = attr_name; - property_flags = attr_flags; - field->generate_var = 1; - } - } 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 if (sym->type == SYMBOL_PROTO) - gen_field_proto(f, field, sym->data); - else { - /* XXX, SYMBOL_TABLE? */ - fprintf(stderr, "%s: wrong type [%d]\n", sym->id, sym->type); - abort(); - } - - if (property_name) { - /* XXX */ - gen_fprintf(f, "<<PROPERTY(%d) %s = FIELD %s>>\n", property_flags, property_name, field->id); - } -} - -static void -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 - gen_fprintf(f, "\twhile ("); - gen_expr(f, &st->w.expr); - gen_fprintf(f, ") {\n"); - - /* gen_fprintf(f, "\tconst int __while%d_offset = %d;\n", _while_id, offset); */ - - parent->cur_offset = -1; - gen_statements(f, parent, st->w.sts); - - /* gen_fprintf(f, "\tassert(__while%d_offset > offset);\n", _while_id, offset); */ - - gen_fprintf(f, "\t}\n"); - return; - - case STATEMENT_STRUCT: - /* XXX, fix if we know size of structure */ - parent->cur_offset = -1; - 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: - gen_statement_field(f, parent, &st->f, st->attr_list); - if (parent->cur_offset != -1) { - if (st->f.field_size != -1) - parent->cur_offset += st->f.field_size; - else - parent->cur_offset = -1; - } - return; - - /* case STATEMENT_DYNAMIC_SWITCH: */ - case STATEMENT_SWITCH: - { - struct npl_switch_case *c = st->sw.data.cases; - - parent->cur_offset = -1; - if (st->sw.data.switch_expr) { - gen_fprintf(f, "\tswitch ("); - gen_expr(f, st->sw.data.switch_expr); - gen_fprintf(f, ") {\n"); - - while (c) { - gen_fprintf(f, "\t\tcase "); - gen_expr(f, &c->e); - gen_fprintf(f, ":\n"); - - if (c->st) { - gen_fprintf(f, "\t\t"); - gen_statement(f, parent, c->st); - gen_fprintf(f, "\t\t\tbreak;\n"); - } - c = c->next; - } - - if (st->sw.data.default_st) { - gen_fprintf(f, "\t\tdefault:\n"); - gen_fprintf(f, "\t\t"); - gen_statement(f, parent, st->sw.data.default_st); - } - - gen_fprintf(f, "\t}\n"); - return; - } - - if (c) { - npl_statement_t *default_st = st->sw.data.default_st; - - gen_fprintf(f, "\t"); - while (c) { - npl_statement_t *case_st; - gen_fprintf(f, "if ("); - - gen_fprintf(f, "("); - gen_expr(f, &c->e); - gen_fprintf(f, ")"); - - case_st = c->st; - c = c->next; - - while (c && !case_st) { - case_st = c->st; - - gen_fprintf(f, " || "); - gen_fprintf(f, "("); - gen_expr(f, &c->e); - gen_fprintf(f, ")"); - c = c->next; - } - - if (!case_st) { - gen_fprintf(f, " || 1"); - case_st = default_st; - default_st = NULL; - } - gen_fprintf(f, ") {\n"); - gen_fprintf(f, "\t"); - gen_statement(f, parent, case_st); - gen_fprintf(f, "\t} "); - - if (c || default_st) - gen_fprintf(f, "else "); - } - - if (default_st) { - gen_fprintf(f, "{\n"); - gen_fprintf(f, "\t"); - gen_statement(f, parent, default_st); - gen_fprintf(f, "\t}\n"); - } - - } else { - if (st->sw.data.default_st) - gen_statement(f, parent, st->sw.data.default_st); - } - return; - } - } - fprintf(stderr, "gen_statement: %d\n", st->type); -} - -static void -gen_statements(FILE *f, struct parent_info *parent, struct _npl_statements *sts) -{ - struct symbol *symroot; - - symroot = symbols_push(); - - while (sts) { - gen_statement(f, parent, &sts->st); - - sts = sts->next; - } - - symbols_pop(symroot); -} - -static void -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; - npl_expression_t *byte_order_attr = NULL; - - p->sym->is_static = 1; - gen_fprintf(f, - "static int\n" - "dissect_%s(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void *data _U_)\n", p->id); - - /* XXX, use data */ - xassert(p->params.count == 0); - - gen_fprintf(f, "{\n"); - gen_fprintf(f, - "\tint offset = 0;\n" - "\tproto_tree *tree = NULL;\n" - "\tproto_item *ti = NULL;\n" - "\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); - - 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"); - - if (p->format) { - /* TODO */ - gen_fprintf(f, "\t\tti = proto_tree_add_protocol_format(parent_tree, proto_%s, tvb, offset, -1, ", p->id); - gen_fprintf(f, "\"TODO\""); - gen_expr(stderr, p->format); - gen_fprintf(f, ");\n"); - } else - gen_fprintf(f, "\t\tti = proto_tree_add_item(parent_tree, proto_%s, tvb, offset, -1, ENC_NA);\n", p->id); - - gen_fprintf(f, "\t\ttree = proto_item_add_subtree(ti, ett_%s);\n", p->id); - gen_fprintf(f, "\t}\n"); - - memset(&this, 0, sizeof(this)); - this.id = p->id; - this.id = NULL; - this.byte_order = 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"); - gen_fprintf(f, "}\n"); - gen_fprintf(f, "\n"); -} - -static void -decl_struct(npl_struct_t *s) -{ - if (!s->sym && s->id) { - s->tmpid = s->id; - s->sym = symbol_add(s->id, SYMBOL_STRUCT, s); - } -} - -static void -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; - - if (!id) { - static unsigned int _id = 0; - char tmp_id[32]; - - snprintf(tmp_id, sizeof(tmp_id), "_noname%u", ++_id); - id = s->tmpid = xstrdup(tmp_id); - - xassert(f == NULL); - } - - if (s->count_expr) { - /* TODO */ - 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" - "{\n", id, s->private ? " _U_" : ""); - - if (!s->private) { - gen_fprintf(f, "\tconst int org_offset = offset;\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,"\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 attr_flags = attr_list->flags; - */ - - if (attr_name) { - fprintf(stderr, "!!! generating struct attr: %s!\n", attr_name); - } else - fprintf(stderr, "!!! generating struct attr: not resolved!\n"); - - attr_list = attr_list->next; - } - - if (!s->private) { -/* - if (s->format) { - fprintf(stderr, "gen_struct() s->format: '"); - gen_expr(stderr, s->format); - fprintf(stderr, "\n\n"); - } - */ - if (!s->ett) - s->ett = ett_add(s); - - gen_fprintf(f, - "\tif (parent_tree) {\n" - "\t\tti = proto_tree_add_bytes_format_value(parent_tree, hf_index, tvb, offset, %d, NULL, \"%s\");\n" - "\t\ttree = proto_item_add_subtree(ti, %s);\n" - "\t}\n", s->struct_size, "", ett_var(s->ett)); - - } else { - if (s->format) - fprintf(stderr, "s->private && s->format?\n"); - } - - memset(&this, 0, sizeof(this)); - this.id = s->id; - - gen_statements(f, &this, s->sts); - s->struct_size = this.cur_offset; - - if (s->struct_size != -1) { - /* XXX, assert runtime s->struct_size == offset - org_offset (?) */ - } - - if (!s->private && s->struct_size == -1) - gen_fprintf(f, "\tproto_item_set_len(ti, offset - org_offset);\n"); - - if (s->struct_size == -1) - s->struct_size = 0; - - gen_fprintf(f, "\treturn offset;\n"); - gen_fprintf(f, "}\n"); - gen_fprintf(f, "\n"); -} - -static void -decl_const(npl_const_t *c) -{ - if (!c->sym) - c->sym = symbol_add(c->id, SYMBOL_EXPR, &c->expr); -} - -#if 0 -static void -gen_const(FILE *f, npl_const_t *c) -{ - gen_fprintf(f, "#define %s ", c->id); - gen_expr(f, &c->expr); - gen_fprintf(f, "\n"); -} -#endif - -static void -decl_type(npl_type_t *t) -{ - if (!t->sym) - t->sym = symbol_add(t->id, SYMBOL_TYPE, t); -} - -static void -walk_decl(FILE *f, npl_decl_t *d, int full_run) -{ - switch (d->type) { - case DECL_STRUCT: - decl_struct(&d->s.data); - if (!full_run) - return; - 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: - decl_protocol(&d->p.data); - if (!full_run) - return; - 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; - } - fprintf(stderr, "gen_decl() type: %d\n", d->type); -} - -static void -walk_code(FILE *f, npl_code_t *c, int full_run) -{ - struct _npl_decl_list *decl; - - for (decl = c->decls; decl; decl = decl->next) - walk_decl(f, &decl->d, 0); - - if (!full_run) - return; - - for (decl = c->decls; decl; decl = decl->next) - walk_decl(f, &decl->d, full_run); -} - -static void -parse_includes(npl_code_t *c) -{ - struct _npl_decl_list *decl; - - for (decl = c->decls; decl; decl = decl->next) { - if (decl->d.type == DECL_INCLUDE) { - const char *filename = decl->d.i.file; - FILE *f; - - npl_code_t icode; - int parse_ok; - - if (!(f = fopen(filename, "rb"))) { - fprintf(stderr, "can't open: %s\n", filename); - abort(); - } - memset(&icode, 0, sizeof(icode)); - parse_ok = npl_parse_file(&icode, f, filename); - fclose(f); - - if (!parse_ok) { - fprintf(stderr, "can't parse %s\n", filename); - abort(); - } - - parse_includes(&icode); - walk_code(NULL, &icode, 0); - } - } -} - -static void -gen_vars(FILE *f) -{ - struct hfinfo *hfi; - struct ettinfo *ett; - - for (hfi = hfs; hfi; hfi = hfi->next) - gen_fprintf(f, "static int %s = -1;\n", hfi_var(hfi)); - gen_fprintf(f, "\n"); - - for (ett = etts; ett; ett = ett->next) - gen_fprintf(f, "static int %s = -1;\n", ett_var(ett)); - gen_fprintf(f, "\n"); -} - -static void -gen_proto_register(FILE *f, const char *proto_name) -{ - struct hfinfo *hfi; - struct ettinfo *ett; - - gen_fprintf(f, - "void\n" - "proto_register_%s(void)\n" - "{\n", proto_name); - - /* hf array */ - gen_fprintf(f, "\tstatic hf_register_info hf[] = {\n"); - for (hfi = hfs; hfi; hfi = hfi->next) { - gen_fprintf(f, - "\t\t{ &%s,\n" - "\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"); - - /* ett array */ - gen_fprintf(f, "\tstatic gint *ett[] = {\n"); - for (ett = etts; ett; ett = ett->next) - gen_fprintf(f, "\t\t&%s,\n", ett_var(ett)); - gen_fprintf(f, "\t};\n\n"); - - - 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\n"); -} - -static void -gen_proto_handoff(FILE *f, const char *proto_name) -{ - gen_fprintf(f, - "void\n" - "proto_reg_handoff_%s(void)\n" - "{\n", proto_name); - - gen_fprintf(f, "\tdissector_handle_t %s_handle = create_dissector_handle(dissect_%s, proto_%s);\n", proto_name, proto_name, proto_name); - -#if 0 - dissector_add_uint("REG", XXX, %s_handle); - - xml_handle = find_dissector("xml"); -#endif - gen_fprintf(f, "}\n\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; -} - -static void -merge_code(npl_code_t *code, npl_code_t *subcode) -{ - struct _npl_decl_list **p = &code->decls; - - while (*p) - p = &(*p)->next; - - *p = subcode->decls; -} - -/* XXX, move to checker.c */ -static void -check_code(npl_code_t *code) -{ - parse_includes(code); - walk_code(NULL, code, 1); -} - -/* XXX, move to generator-c.c */ -static void -generate_code(npl_code_t *code) -{ - const npl_protocol_t *proto = get_protocol(code); - const char *proto_name = (proto) ? proto->id : "noname"; - FILE *out; - struct symbol *sym; - - out = fopen("/tmp/npl.c", "w"); - - /* 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"); - - /* 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); - - gen_proto_register(out, proto_name); - gen_proto_handoff(out, proto_name); - - fclose(out); -} - -int main(int argc, char **argv) { - FILE *f; - npl_code_t code; - - int i; - - if (argc < 2) { - fprintf(stderr, "usage: %s filename\n", argv[0]); - return 1; - } - - /* build-in expressions */ - symbol_add("FrameOffset", SYMBOL_SIMPLE, "offset"); - symbol_add("FrameData", SYMBOL_SIMPLE, "tvb"); - symbol_add("this", SYMBOL_EXPR, &this_e); - - /* built-in functions */ - symbol_add("FormatString", SYMBOL_EXPR, &format_string_e); - symbol_add("IsValueNone", SYMBOL_EXPR, &is_value_none_e); - - /* built-in structs (?) */ - symbol_add("Property", SYMBOL_EXPR, &property_e); /* XXX, SYMBOL_STRUCT */ - symbol_add("Global", SYMBOL_EXPR, &global_e); /* XXX, SYMBOL_STRUCT */ - symbol_add("Local", SYMBOL_EXPR, &local_e); /* XXX, SYMBOL_STRUCT */ - - memset(&code, 0, sizeof(code)); - - for (i = 1; i < argc; i++) { - npl_code_t mcode; - int parse_ok; - - if (!(f = fopen(argv[i], "rb"))) { - fprintf(stderr, "can't open: %s\n", argv[i]); - continue; - return 1; - } - - memset(&mcode, 0, sizeof(mcode)); - parse_ok = npl_parse_file(&mcode, f, argv[i]); - fclose(f); - - if (!parse_ok) { - fprintf(stderr, "can't parse: %s\n", argv[i]); - return 1; - } - - merge_code(&code, &mcode); - } - - check_code(&code); - generate_code(&code); - - return 0; -} - -/* - * Editor modelines - https://www.wireshark.org/tools/modelines.html - * - * Local variables: - * c-basic-offset: 8 - * tab-width: 8 - * indent-tabs-mode: t - * End: - * - * vi: set shiftwidth=8 tabstop=8 noexpandtab: - * :indentSize=8:tabSize=8:noTabs=false: - */ |