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 | |
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')
-rw-r--r-- | tools/npl/ast.h | 419 | ||||
-rw-r--r-- | tools/npl/npl.c | 1993 | ||||
-rw-r--r-- | tools/npl/parser.l | 1429 | ||||
-rw-r--r-- | tools/npl/xmem.h | 26 |
4 files changed, 0 insertions, 3867 deletions
diff --git a/tools/npl/ast.h b/tools/npl/ast.h deleted file mode 100644 index 67ce4e31d7..0000000000 --- a/tools/npl/ast.h +++ /dev/null @@ -1,419 +0,0 @@ -/** @file - * - * Copyright 2012-2013, Jakub Zawadzki <darkjames-ws@darkjames.pl> - * - * SPDX-License-Identifier: GPL-2.0-or-later - */ - -typedef enum { - OP1_INVALID = 0, - OP1_MINUS, - OP1_NOT, - OP1_NEG -} npl_op1_t; - -typedef enum { - OP2_INVALID = 0, - - OP2_ASSIGN, - OP2_ASSIGN_PLUS, - - OP2_PLUS, - OP2_MINUS, - - OP2_MULTIPLY, - OP2_DIV, - OP2_MOD, - - OP2_SHL, - OP2_SHR, - - OP2_EQUAL, - OP2_NOTEQUAL, - - OP2_LESS, - OP2_GREATER, - OP2_LEQUAL, - OP2_GEQUAL, - - OP2_LOGIC_OR, - OP2_LOGIC_AND, - - OP2_OR, - OP2_AND, - OP2_XOR, - -} npl_op2_t; - -#define NPL_PARAMS_MAX 20 - -typedef struct { - char *args[NPL_PARAMS_MAX]; - int count; - -} npl_params_t; - -typedef enum { - EXPRESSION_INVALID = 0, - - EXPRESSION_ID, - EXPRESSION_INT, - EXPRESSION_STR, - - EXPRESSION_INDEX, - EXPRESSION_MULTI_INDEX, - EXPRESSION_FIELD, - EXPRESSION_CALL, - - EXPRESSION_UNARY, - EXPRESSION_BINARY, - EXPRESSION_COND - -} 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 { - npl_expression_type_t type; - }; - - struct { - npl_expression_type_t type; /* EXPRESSION_ID */ - char *id; - } id; - - struct { - npl_expression_type_t type; /* EXPRESSION_INT */ - unsigned int digit; - } num; - - struct { - npl_expression_type_t type; /* EXPRESSION_STR */ - char *str; - } str; - - struct { - npl_expression_type_t type; /* EXPRESSION_INDEX */ - - struct _npl_expression *base; - struct _npl_expression *index; - } 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; - char *field; - } fld; - - struct { - npl_expression_type_t type; /* EXPRESSION_UNARY */ - - npl_op1_t operator; - struct _npl_expression *operand; - - } u; - - struct { - npl_expression_type_t type; /* EXPRESSION_BINARY */ - - struct _npl_expression *operand1; - struct _npl_expression *operand2; - npl_op2_t operator; - - } b; - - struct { - npl_expression_type_t type; /* EXPRESSION_CALL */ - - struct _npl_expression *fn; - npl_expression_list_t *args; - - } call; - - struct { - npl_expression_type_t type; /* EXPRESSION_COND */ - - struct _npl_expression *test_expr; - struct _npl_expression *true_expr; - struct _npl_expression *false_expr; - } c; - - -}; -} npl_expression_t; - -struct _npl_statement; - -typedef struct { - char *id; - int private; - npl_params_t params; - - npl_expression_t *format; - npl_expression_t *count_expr; - struct _npl_statements *sts; - - /* code generator */ - char *tmpid; - struct ettinfo *ett; - struct symbol *sym; - int struct_size; -} npl_struct_t; - -typedef struct { - char *id; - npl_params_t params; - - npl_expression_t *switch_expr; - - struct npl_table_case { - struct npl_table_case *next; - - npl_expression_t e; - - npl_expression_t *return_expr; - - } *cases; - - npl_expression_t *default_expr; - - /* code generator */ - struct symbol *sym; -} npl_table_t; - -typedef struct { - char *id; - npl_expression_t expr; - - /* code generator */ - struct symbol *sym; -} npl_const_t; - -typedef enum { - STATEMENT_INVALID = 0, - - STATEMENT_WHILE, - STATEMENT_TABLE, - STATEMENT_STRUCT, - STATEMENT_FIELD, - STATEMENT_SWITCH, - STATEMENT_DYNAMIC_SWITCH, - -} npl_statement_type_t; - -typedef struct { - npl_expression_t *switch_expr; - - struct npl_switch_case { - struct npl_switch_case *next; - - npl_expression_t e; - - struct _npl_statement *st; - - } *cases; - - struct _npl_statement *default_st; - -} 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; - - struct _npl_statements *sts; - } w; - - 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; - - unsigned int bits; - npl_expression_t *arr; - - npl_expression_t *format; - struct _npl_statements *sts; - npl_expression_list_t *params; - - /* code generator */ - struct hfinfo *hfi; - npl_expression_t *byte_order_attr; - int generate_var; - int field_size; - } f; - - }; -} npl_statement_t; - -struct _npl_statements { - struct _npl_statements *next; - - npl_statement_t st; -}; - -typedef struct { - char *id; - npl_params_t params; - - npl_expression_t *format; - struct _npl_statements *sts; - - /* code generator */ - struct symbol *sym; -} npl_protocol_t; - -typedef enum { - FIELD_INVALID = 0, - - FIELD_DECIMAL, - FIELD_NUMBER, - FIELD_TIME, - FIELD_UNSIGNED_NUMBER - -} npl_field_type_t; - -typedef struct { - npl_field_type_t type; - - char *id; - npl_params_t params; - - npl_expression_t *byte_order; - npl_expression_t *display_format; - npl_expression_t *size; - - /* code generator */ - struct symbol *sym; - -} npl_type_t; - -typedef enum { - DECL_INVALID = 0, - - DECL_INCLUDE, - DECL_STRUCT, - DECL_TABLE, - DECL_CONST, - DECL_PROTOCOL, - DECL_TYPE - -} npl_decl_type_t; - -typedef struct { - union { - struct { - npl_decl_type_t type; - npl_attribute_list_t *attr_list; - }; - - 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; - - }; -} npl_decl_t; - -typedef struct { - struct _npl_decl_list { - struct _npl_decl_list *next; - npl_decl_t d; - - } *decls; - -} npl_code_t; 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: - */ diff --git a/tools/npl/parser.l b/tools/npl/parser.l deleted file mode 100644 index 00d39923a4..0000000000 --- a/tools/npl/parser.l +++ /dev/null @@ -1,1429 +0,0 @@ -/* - * Copyright 2012-2013, Jakub Zawadzki <darkjames-ws@darkjames.pl> - * - * SPDX-License-Identifier: GPL-2.0-or-later - */ - -%option noyywrap -%option nounput - -%option noyy_scan_buffer -%option noyy_scan_bytes -%option noyy_scan_string - -%option yylineno -%option never-interactive - -%option case-insensitive - -%{ -#define YY_DECL static token_type_t yylex(void) - -#include <setjmp.h> -#include "ast.h" -#include "xmem.h" - -typedef enum { - TOKEN_ERROR = -1, - TOKEN_EOF = 0, - - TOKEN_INCLUDE, - TOKEN_STRUCT, - TOKEN_PRIVATE_STRUCT, - TOKEN_CONST, - TOKEN_PROTOCOL, - - TOKEN_WHILE, - - TOKEN_DYNAMIC_SWITCH, - TOKEN_SWITCH, - TOKEN_TABLE, - TOKEN_CASE, - TOKEN_DEFAULT, - - TOKEN_ID, - TOKEN_STR, - TOKEN_CHAR, - TOKEN_DIGIT, - TOKEN_FLOAT, - - TOKEN_LPAREN, - TOKEN_RPAREN, - TOKEN_LBRACKET, - TOKEN_RBRACKET, - TOKEN_LCURLY, - TOKEN_RCURLY, - - TOKEN_ANDAND, - TOKEN_OROR, - - TOKEN_EQUAL, - TOKEN_NOTEQUAL, - TOKEN_NOTEQUAL2, - - TOKEN_LEQUAL, - TOKEN_GEQUAL, - - TOKEN_ASSIGN, - TOKEN_ASSIGN_PLUS, - TOKEN_PLUS, - TOKEN_MINUS, - TOKEN_MULTIPLY, - TOKEN_DIV, - TOKEN_LOGIC_OR, - TOKEN_OR, - TOKEN_LOGIC_AND, - TOKEN_AND, - TOKEN_NOT, - TOKEN_NEG, - TOKEN_XOR, - - TOKEN_SHL, - TOKEN_SHR, - - TOKEN_PERCENT, - TOKEN_DOLLAR, - TOKEN_COND, - TOKEN_COLON, - - TOKEN_SEMICOLON, - TOKEN_DOT, - TOKEN_COMMA, - - TOKEN_LESS, - TOKEN_GREATER, - - TOKEN_NUMBER, - TOKEN_UNSIGNED_NUMBER, - TOKEN_DECIMAL, - TOKEN_TIME, - TOKEN_BYTE_ORDER, - TOKEN_DISPLAY_FORMAT, - TOKEN_SIZE - -} token_type_t; - -%} - -%x cppcomment -%x lch -%x lstr -%x lstrescape - -DIGIT10 [0-9] -DIGIT16 [0-9a-fA-F] - -ID [_a-zA-Z][_a-zA-Z0-9]* - -%% - -include return TOKEN_INCLUDE; -struct return TOKEN_STRUCT; -_struct return TOKEN_PRIVATE_STRUCT; - -const return TOKEN_CONST; -protocol return TOKEN_PROTOCOL; - -while return TOKEN_WHILE; - -DynamicSwitch return TOKEN_DYNAMIC_SWITCH; -switch return TOKEN_SWITCH; -table return TOKEN_TABLE; -case return TOKEN_CASE; -default return TOKEN_DEFAULT; - -Number return TOKEN_NUMBER; -UnsignedNumber return TOKEN_UNSIGNED_NUMBER; -Decimal return TOKEN_DECIMAL; -Time return TOKEN_TIME; -ByteOrder return TOKEN_BYTE_ORDER; -DisplayFormat return TOKEN_DISPLAY_FORMAT; -Size return TOKEN_SIZE; - -"(" return TOKEN_LPAREN; -")" return TOKEN_RPAREN; -"[" return TOKEN_LBRACKET; -"]" return TOKEN_RBRACKET; -"{" return TOKEN_LCURLY; -"}" return TOKEN_RCURLY; - -and return TOKEN_ANDAND; -or return TOKEN_OROR; - -"==" return TOKEN_EQUAL; -"!=" return TOKEN_NOTEQUAL; -"<>" return TOKEN_NOTEQUAL2; - -">=" return TOKEN_GEQUAL; -"<=" return TOKEN_LEQUAL; - -"+=" return TOKEN_ASSIGN_PLUS; -"=" return TOKEN_ASSIGN; -"+" return TOKEN_PLUS; -"-" return TOKEN_MINUS; -"*" return TOKEN_MULTIPLY; -"/" return TOKEN_DIV; -"||" return TOKEN_LOGIC_OR; -"|" return TOKEN_OR; -"&&" return TOKEN_LOGIC_AND; -"&" return TOKEN_AND; -"!" return TOKEN_NOT; -"~" return TOKEN_NEG; -"^" return TOKEN_XOR; -"<<" return TOKEN_SHL; -">>" return TOKEN_SHR; -"%" return TOKEN_PERCENT; -"$" return TOKEN_DOLLAR; -"?" return TOKEN_COND; - -";" return TOKEN_SEMICOLON; -"." return TOKEN_DOT; -"," return TOKEN_COMMA; -":" return TOKEN_COLON; - -"<" return TOKEN_LESS; -">" return TOKEN_GREATER; - -"'" yymore(); BEGIN(lch); -<lch>{ - "'" BEGIN(INITIAL); return TOKEN_CHAR; - "\n" return TOKEN_ERROR; - . yymore(); -} - -"\"" yymore(); BEGIN(lstr); -<lstr>{ - "\"" BEGIN(INITIAL); return TOKEN_STR; - "\\" yymore(); BEGIN(lstrescape); - "\n" return TOKEN_ERROR; - . yymore(); -} - -<lstrescape>{ - "\n" return TOKEN_ERROR; - . yymore(); BEGIN(lstr); -} - -"//" BEGIN(cppcomment); -<cppcomment>{ - "\n" BEGIN(INITIAL); - . ; -} - -"/*" { - int nested = 1; - int ch, last_ch; - - last_ch = '*'; - - /* XXX, can comments be nested? (can't be determinated by current example file set) */ - - do { - ch = input(); - - if (last_ch == '*' && ch == '/') - nested--; - - if (last_ch == '/' && ch == '*') - nested++; - - if (ch == EOF) - return TOKEN_ERROR; - - last_ch = ch; - - } while(nested); -} - -{ID} return TOKEN_ID; -{DIGIT10}+"."{DIGIT10}* return TOKEN_FLOAT; -{DIGIT10}+ return TOKEN_DIGIT; -"0x"{DIGIT16}+ return TOKEN_DIGIT; - -[[:space:]] ; - -. return TOKEN_ERROR; - -%% - -static const char *yyfilename; -static int token; - -static const char *token_name(token_type_t tok) { - static char buf[64]; - - switch (tok) { - case TOKEN_EOF: return "<<eof>>"; - case TOKEN_ERROR: return "<<error>>"; - - case TOKEN_ID: - return "<ID>"; - case TOKEN_STR: - return "<STR>"; - case TOKEN_CHAR: - return "<CHAR>"; - case TOKEN_DIGIT: - return "<DIGIT>"; - case TOKEN_FLOAT: - return "<FLOAT>"; - - case TOKEN_STRUCT: - return "struct"; - case TOKEN_PRIVATE_STRUCT: - return "_struct"; - case TOKEN_CONST: - return "const"; - case TOKEN_WHILE: - return "while"; - case TOKEN_SWITCH: - return "switch"; - case TOKEN_DYNAMIC_SWITCH: - return "dynamic switch"; - case TOKEN_CASE: - return "case"; - - /* ... */ - default: - ; - } - - snprintf(buf, sizeof(buf), "<token #%d>", 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); } - -static void _strange(int line) { - fprintf(stdout, "?!?!? %s:%d got: %d (%s) @%s:%d\n", __FILE__, line, token, yytext, yyfilename, yylineno); -} -#define strange() _strange(__LINE__) - -static void _nomatch(int line) { - fprintf(stdout, "!!!! %s:%d got: %d (%s) @%s:%d\n", __FILE__, line, token, yytext, yyfilename, yylineno); - 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); - xfail(); - } - next_token(); -} -#define accept(tok) _accept(tok, __LINE__) - -static int is_id(void) { - /* Some NPL files use keyword as ID (sucks...) */ - return - is_token(TOKEN_PROTOCOL) || - is_token(TOKEN_SIZE) || - is_token(TOKEN_DEFAULT) || - is_token(TOKEN_NUMBER) || - is_token(TOKEN_DECIMAL) || - is_token(TOKEN_TIME) || - is_token(TOKEN_BYTE_ORDER) || - is_token(TOKEN_OROR) || is_token(TOKEN_ANDAND) || - is_token(TOKEN_STRUCT) || is_token(TOKEN_TABLE) || - is_token(TOKEN_ID); -} - -static char *_accept_id(int line) { - char *id; - - 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); - xfail(); - } - - id = xstrdup(yytext); - next_token(); - - return id; -} - -#define accept_id() _accept_id(__LINE__) - -static unsigned int _accept_int(int line) { - unsigned int num; - - 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); - xfail(); - } - - if (yytext[0] == '0' && yytext[1] == 'x') - num = strtol(yytext + 2, NULL, 16); - else - num = strtol(yytext, NULL, 10); - - next_token(); - - return num; -} - -#define accept_int() _accept_int(__LINE__) - - -static char *_accept_str(int line) { - size_t len; - char *str; - - 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); - xfail(); - } - - len = strlen(yytext); - - if (len < 2 || yytext[0] != '"' || yytext[len-1] != '"') - xfail(); -#if 0 - char *ptr; - size_t i; - - ptr = str = xmalloc(len-2+1); - for (i = 1; i < len-1; i++) { - if (yytext[i] == '\\') { - i++; - - if (yytext[i] == '0' && yytext[i+1] == 'x') { - i += 2; - - // XXX - *ptr++ = yytext[i]; - } else - switch (yytext[i]) { - case '0': - *ptr++ = '\0'; - break; - case '\\': - *ptr++ = '\\'; - break; - case 'r': - *ptr++ = '\r'; - break; - case 'n': - *ptr++ = '\n'; - break; - case 't': - *ptr++ = '\t'; - break; - - case '"': - *ptr++ = '"'; - break; - case '\'': - *ptr++ = '\''; - break; - - default: - fprintf(stdout, "unrecog: %c @ %d\n", yytext[i], yylineno); - *ptr++ = yytext[i]; - } - - } else - *ptr++ = yytext[i]; - } - - *ptr = '\0'; -#else - len -= 2; - /* escaping is done almost like in C so don't unescape (cause it'd require escaping later...) */ - str = xmalloc(len + 1); - memcpy(str, yytext + 1, len); - str[len] = '\0'; -#endif - - next_token(); - - return str; -} -#define accept_str() _accept_str(__LINE__) - -static int is_token_accept(token_type_t tok) { - if (is_token(tok)) { - next_token(); - return 1; - } - return 0; -} - -static int is_params(void) { return is_token(TOKEN_LPAREN); } - -static void -parse_params(npl_params_t *p) -{ - int i = 0; - - accept(TOKEN_LPAREN); - do { - if (i == NPL_PARAMS_MAX) { - fprintf(stdout, "i == NPL_PARAMS_MAX"); - xfail(); - } - - p->args[i++] = accept_id(); - - } while (is_token_accept(TOKEN_COMMA)); - accept(TOKEN_RPAREN); - - p->count = i; -} - -static void parse_expression(npl_expression_t *expr); -static npl_expression_t *xparse_expression(void); - -static void -parse_primary(npl_expression_t *expr) -{ - if (is_id()) { - expr->type = EXPRESSION_ID; - expr->id.id = accept_id(); - return; - } - - if (is_token(TOKEN_DIGIT)) { - expr->type = EXPRESSION_INT; - expr->num.digit = accept_int(); - return; - } - - if (is_token(TOKEN_FLOAT)) { - // XXX ast - accept(TOKEN_FLOAT); - expr->type = -1; - return; - } - - if (is_token(TOKEN_CHAR)) { - // XXX ast - accept(TOKEN_CHAR); - expr->type = -2; - return; - } - - if (is_token(TOKEN_STR)) { - expr->type = EXPRESSION_STR; - expr->str.str = accept_str(); - return; - } - - if (is_token_accept(TOKEN_LPAREN)) { - parse_expression(expr); - accept(TOKEN_RPAREN); - return; - } - - 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) -{ - parse_primary(expr); - - do { - if (is_token_accept(TOKEN_LPAREN)) { /* foo() */ - npl_expression_t *fun = xdup(npl_expression_t, expr); - npl_expression_list_t *args = NULL; - - if (!is_token(TOKEN_RPAREN)) - parse_expression_list(&args); - accept(TOKEN_RPAREN); - - expr->type = EXPRESSION_CALL; - expr->call.fn = fun; - expr->call.args = args; - - } else if (is_token_accept(TOKEN_DOLLAR)) { /* arr$[field1, field2, ...] */ - npl_expression_t *base = xdup(npl_expression_t, expr); - npl_expression_list_t *indexes; - - accept(TOKEN_LBRACKET); - parse_expression_list(&indexes); - accept(TOKEN_RBRACKET); - - expr->type = EXPRESSION_MULTI_INDEX; - expr->aarr.base = base; - expr->aarr.indexes = indexes; - - } 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; - expr->arr.base = base; - expr->arr.index = idx; - - } else if (is_token_accept(TOKEN_DOT)) { - npl_expression_t *base = xdup(npl_expression_t, expr); - char *field; - - field = accept_id(); - - expr->type = EXPRESSION_FIELD; - expr->fld.base = base; - expr->fld.field = field; - - } else - break; - - } while (1); -} - -static void -parse_expression2(npl_expression_t *expr) -{ - npl_op1_t op; - - do { - op = - (is_token_accept(TOKEN_MINUS)) ? OP1_MINUS : - (is_token_accept(TOKEN_NOT)) ? OP1_NOT : - (is_token_accept(TOKEN_NEG)) ? OP1_NEG : - OP1_INVALID; - - if (op != OP1_INVALID) { - expr->type = EXPRESSION_UNARY; - expr->u.operator = op; - - expr = expr->u.operand = xnew(npl_expression_t); - } - } while (op != OP1_INVALID); - - parse_expression1(expr); -} - -static void -parse_expression3(npl_expression_t *expr) -{ - npl_op2_t op; - - parse_expression2(expr); -again: - op = - (is_token_accept(TOKEN_MULTIPLY)) ? OP2_MULTIPLY : - (is_token_accept(TOKEN_DIV)) ? OP2_DIV : - (is_token_accept(TOKEN_PERCENT)) ? OP2_MOD : - OP2_INVALID; - - if (op != OP2_INVALID) { - npl_expression_t *operand = xdup(npl_expression_t, expr); - npl_expression_t *e; - - expr->b.operand2 = e = xnew(npl_expression_t); - parse_expression3(e); - - expr->b.operator = op; - expr->b.operand1 = operand; - expr->type = EXPRESSION_BINARY; - goto again; - } -} - -static void -parse_expression4(npl_expression_t *expr) -{ - npl_op2_t op; - - parse_expression3(expr); -again: - op = - (is_token_accept(TOKEN_PLUS)) ? OP2_PLUS : - (is_token_accept(TOKEN_MINUS)) ? OP2_MINUS : - OP2_INVALID; - - if (op != OP2_INVALID) { - npl_expression_t *operand = xdup(npl_expression_t, expr); - npl_expression_t *e; - - expr->b.operand2 = e = xnew(npl_expression_t); - parse_expression4(e); - - expr->b.operator = op; - expr->b.operand1 = operand; - expr->type = EXPRESSION_BINARY; - goto again; - } -} - -static void -parse_expression5(npl_expression_t *expr) -{ - npl_op2_t op; - - parse_expression4(expr); -again: - op = - (is_token_accept(TOKEN_SHL)) ? OP2_SHL : - (is_token_accept(TOKEN_SHR)) ? OP2_SHR : - OP2_INVALID; - - if (op != OP2_INVALID) { - npl_expression_t *operand = xdup(npl_expression_t, expr); - npl_expression_t *e; - - expr->b.operand2 = e = xnew(npl_expression_t); - parse_expression5(e); - - expr->b.operator = op; - expr->b.operand1 = operand; - expr->type = EXPRESSION_BINARY; - goto again; - } -} - -static void -parse_expression6(npl_expression_t *expr) -{ - npl_op2_t op; - - parse_expression5(expr); -again: - op = - (is_token_accept(TOKEN_LESS)) ? OP2_LESS : - (is_token_accept(TOKEN_GREATER)) ? OP2_GREATER : - (is_token_accept(TOKEN_LEQUAL)) ? OP2_LEQUAL : - (is_token_accept(TOKEN_GEQUAL)) ? OP2_GEQUAL : - OP2_INVALID; - - if (op != OP2_INVALID) { - npl_expression_t *operand = xdup(npl_expression_t, expr); - npl_expression_t *e; - - expr->b.operand2 = e = xnew(npl_expression_t); - parse_expression6(e); - - expr->b.operator = op; - expr->b.operand1 = operand; - expr->type = EXPRESSION_BINARY; - goto again; - } -} - -static void -parse_expression7(npl_expression_t *expr) -{ - npl_op2_t op; - - parse_expression6(expr); -again: - op = - (is_token_accept(TOKEN_EQUAL)) ? OP2_EQUAL : - (is_token_accept(TOKEN_NOTEQUAL)) ? OP2_NOTEQUAL : - (is_token_accept(TOKEN_NOTEQUAL2)) ? OP2_NOTEQUAL : - OP2_INVALID; - - if (op != OP2_INVALID) { - npl_expression_t *operand = xdup(npl_expression_t, expr); - npl_expression_t *e; - - expr->b.operand2 = e = xnew(npl_expression_t); - parse_expression7(e); - - expr->b.operator = op; - expr->b.operand1 = operand; - expr->type = EXPRESSION_BINARY; - goto again; - } -} - -static void -parse_expression8(npl_expression_t *expr) -{ - parse_expression7(expr); -again: - if (is_token_accept(TOKEN_AND)) { - npl_expression_t *operand = xdup(npl_expression_t, expr); - npl_expression_t *e; - - expr->b.operand2 = e = xnew(npl_expression_t); - parse_expression8(e); - - expr->b.operator = OP2_AND; - expr->b.operand1 = operand; - expr->type = EXPRESSION_BINARY; - goto again; - } -} - -static void -parse_expression9(npl_expression_t *expr) -{ - parse_expression8(expr); -again: - if (is_token_accept(TOKEN_XOR)) { - npl_expression_t *operand = xdup(npl_expression_t, expr); - npl_expression_t *e; - - expr->b.operand2 = e = xnew(npl_expression_t); - parse_expression9(e); - - expr->b.operator = OP2_XOR; - expr->b.operand1 = operand; - expr->type = EXPRESSION_BINARY; - goto again; - } -} - -static void -parse_expression10(npl_expression_t *expr) -{ - parse_expression9(expr); -again: - if (is_token_accept(TOKEN_OR)) { - npl_expression_t *operand = xdup(npl_expression_t, expr); - npl_expression_t *e; - - expr->b.operand2 = e = xnew(npl_expression_t); - parse_expression10(e); - - expr->b.operator = OP2_OR; - expr->b.operand1 = operand; - expr->type = EXPRESSION_BINARY; - goto again; - } -} - -static void -parse_expression11(npl_expression_t *expr) -{ - npl_op2_t op; - - parse_expression10(expr); -again: - op = - (is_token_accept(TOKEN_LOGIC_AND)) ? OP2_LOGIC_AND : - (is_token_accept(TOKEN_ANDAND)) ? OP2_LOGIC_AND : - OP2_INVALID; - - if (op != OP2_INVALID) { - npl_expression_t *operand = xdup(npl_expression_t, expr); - npl_expression_t *e; - - expr->b.operand2 = e = xnew(npl_expression_t); - parse_expression11(e); - - expr->b.operator = op; - expr->b.operand1 = operand; - expr->type = EXPRESSION_BINARY; - goto again; - } -} - -static void -parse_expression12(npl_expression_t *expr) -{ - npl_op2_t op; - - parse_expression11(expr); -again: - op = - (is_token_accept(TOKEN_LOGIC_OR)) ? OP2_LOGIC_OR : - (is_token_accept(TOKEN_OROR)) ? OP2_LOGIC_OR : - OP2_INVALID; - - if (op != OP2_INVALID) { - npl_expression_t *operand = xdup(npl_expression_t, expr); - npl_expression_t *e; - - expr->b.operand2 = e = xnew(npl_expression_t); - parse_expression12(e); - - expr->b.operator = op; - expr->b.operand1 = operand; - expr->type = EXPRESSION_BINARY; - goto again; - } -} - -static void -parse_expression13(npl_expression_t *expr) -{ - parse_expression12(expr); - - if (is_token_accept(TOKEN_COND)) { - npl_expression_t *operand = xdup(npl_expression_t, expr); - npl_expression_t *e; - - expr->c.test_expr = operand; - - e = xnew(npl_expression_t); - parse_expression(e); - expr->c.true_expr = e; - accept(TOKEN_COLON); - - e = xnew(npl_expression_t); - parse_expression13(e); - expr->c.false_expr = e; - - expr->type = EXPRESSION_COND; - } -} - -static npl_expression_t * -xparse_expression(void) -{ - npl_expression_t *expr = xnew(npl_expression_t); - - parse_expression(expr); - return expr; -} - -static void -parse_expression(npl_expression_t *expr) -{ - npl_op2_t op; - - parse_expression13(expr); - - op = - (is_token_accept(TOKEN_ASSIGN)) ? OP2_ASSIGN : - (is_token_accept(TOKEN_ASSIGN_PLUS)) ? OP2_ASSIGN_PLUS : - OP2_INVALID; - - if (op != OP2_INVALID) { - npl_expression_t *operand = xdup(npl_expression_t, expr); - - expr->b.operand2 = xparse_expression(); - - expr->b.operator = op; - expr->b.operand1 = operand; - expr->type = EXPRESSION_BINARY; - } -} - -static int is_attribute(void) { return is_token(TOKEN_LBRACKET); } - -static npl_attribute_list_t ** -pparse_attributes(npl_attribute_list_t **ptr) -{ - accept(TOKEN_LBRACKET); - - do { - npl_attribute_list_t *cur = xnew(npl_attribute_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); - 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); - -static npl_statement_t * -xparse_statement(void) -{ - npl_statement_t *st = xnew(npl_statement_t); - - parse_statement(st); - return st; -} - -static void -parse_switch_body(npl_switch_t *sw) -{ - struct npl_switch_case **ptr = &sw->cases; - - while (is_token(TOKEN_CASE)) { - struct npl_switch_case *cur = xnew(struct npl_switch_case); - - *ptr = cur; - - ptr = &(cur->next); - - accept(TOKEN_CASE); - parse_expression(&cur->e); - accept(TOKEN_COLON); - - if (!is_token(TOKEN_CASE) && !is_token(TOKEN_DEFAULT)) { - cur->st = xparse_statement(); - is_token_accept(TOKEN_SEMICOLON); - } - } - *ptr = NULL; - - if (is_token_accept(TOKEN_DEFAULT)) { - accept(TOKEN_COLON); - sw->default_st = xparse_statement(); - } -} - -static void -parse_switch(npl_switch_t *sw) -{ - accept(TOKEN_SWITCH); - - if (is_token_accept(TOKEN_LPAREN)) { - sw->switch_expr = xparse_expression(); - accept(TOKEN_RPAREN); - } - - accept(TOKEN_LCURLY); - parse_switch_body(sw); - accept(TOKEN_RCURLY); - is_token_accept(TOKEN_SEMICOLON); -} - -static void -parse_dynamic_switch(npl_switch_t *sw) -{ - accept(TOKEN_DYNAMIC_SWITCH); - - sw->switch_expr = xparse_expression(); - - accept(TOKEN_LCURLY); - parse_switch_body(sw); - accept(TOKEN_RCURLY); - is_token_accept(TOKEN_SEMICOLON); -} - -static int is_statement(void) { - return - is_token(TOKEN_WHILE) || - is_token(TOKEN_TABLE) || - is_token(TOKEN_STRUCT) || is_token(TOKEN_PRIVATE_STRUCT) || - is_token(TOKEN_SWITCH) || is_token(TOKEN_DYNAMIC_SWITCH) || - is_id() || is_attribute() || -#if 1 - is_token(TOKEN_SEMICOLON) || -#endif - 0 - ; -} - -/* Statements = { Statement } ; */ -static struct _npl_statements * -xparse_statements(void) -{ - struct _npl_statements *ret; - struct _npl_statements **ptr = &ret; - - while (is_statement()) { - struct _npl_statements *cur = xnew(struct _npl_statements); - - parse_statement(&cur->st); - - *ptr = cur; - ptr = &(cur->next); - } - *ptr = NULL; - - return ret; -} - -static void -parse_while(npl_statement_t *st) -{ - accept(TOKEN_WHILE); - - if (is_id()) - st->w.id = accept_id(); - - accept(TOKEN_LBRACKET); - parse_expression(&st->w.expr); - accept(TOKEN_RBRACKET); - - accept(TOKEN_LCURLY); - st->w.sts = xparse_statements(); - accept(TOKEN_RCURLY); - is_token_accept(TOKEN_SEMICOLON); -} - -static int is_formatting(void) { return is_token(TOKEN_ASSIGN); } - -/* Formatting = "=", Expression ; */ -static npl_expression_t * -xparse_formatting(void) -{ - npl_expression_t *format; - - accept(TOKEN_ASSIGN); - - format = xnew(npl_expression_t); - parse_expression(format); - return format; -} - -static void parse_table(npl_table_t *); -static void parse_struct(npl_struct_t *s, int statement); - -static void -parse_statement(npl_statement_t *st) -{ - parse_all_attributes(&st->attr_list); - - if (is_token(TOKEN_WHILE)) { - parse_while(st); - st->type = STATEMENT_WHILE; - return; - } - - if (is_token(TOKEN_TABLE)) { - parse_table(&st->t.data); - st->type = STATEMENT_TABLE; - return; - } - - if (is_token(TOKEN_STRUCT) || is_token(TOKEN_PRIVATE_STRUCT)) { - parse_struct(&st->s.data, 1); - st->type = STATEMENT_STRUCT; - return; - } - - if (is_token(TOKEN_SWITCH)) { - parse_switch(&(st->sw.data)); - st->type = STATEMENT_SWITCH; - return; - } - - if (is_token(TOKEN_DYNAMIC_SWITCH)) { - parse_dynamic_switch(&(st->sw.data)); - st->type = STATEMENT_DYNAMIC_SWITCH; - return; - } -#if 1 - if (is_token(TOKEN_SEMICOLON)) { - accept(TOKEN_SEMICOLON); - st->type = -3; - return; - } -#endif - - st->type = STATEMENT_FIELD; - st->f.t_id = accept_id(); - - if (is_token_accept(TOKEN_LPAREN)) { - parse_expression_list(&st->f.params); - accept(TOKEN_RPAREN); - - } else - st->f.params = NULL; - - st->f.id = accept_id(); - if (is_token_accept(TOKEN_COLON)) - st->f.bits = accept_int(); - - else if (is_token_accept(TOKEN_LBRACKET)) { - st->f.arr = xparse_expression(); - accept(TOKEN_RBRACKET); - } - - if (is_formatting()) - st->f.format = xparse_formatting(); - - if (is_token_accept(TOKEN_LCURLY)) { - st->f.sts = xparse_statements(); - accept(TOKEN_RCURLY); - is_token_accept(TOKEN_SEMICOLON); - return; - } - - accept(TOKEN_SEMICOLON); -} - -/* Protocol = "protocol", ID, [Params], [Formatting], "{", Statements, "}", ";" ; */ -static void -parse_protocol(npl_protocol_t *p) -{ - accept(TOKEN_PROTOCOL); - p->id = accept_id(); - - if (is_params()) - parse_params(&p->params); - - if (is_formatting()) - p->format = xparse_formatting(); - - accept(TOKEN_LCURLY); - p->sts = xparse_statements(); - accept(TOKEN_RCURLY); - is_token_accept(TOKEN_SEMICOLON); -} - -static void -parse_struct(npl_struct_t *s, int statement) -{ - if (is_token_accept(TOKEN_STRUCT)) - s->private = 0; - else if (is_token_accept(TOKEN_PRIVATE_STRUCT)) - s->private = 1; - else - nomatch(); - - if (!statement || is_id()) - s->id = accept_id(); - - if (is_params()) - parse_params(&s->params); - - if (statement) { - if (is_token_accept(TOKEN_LBRACKET)) { - s->count_expr = xparse_expression(); - accept(TOKEN_RBRACKET); - } - } - - if (is_formatting()) - s->format = xparse_formatting(); - - accept(TOKEN_LCURLY); - s->sts = xparse_statements(); - accept(TOKEN_RCURLY); - is_token_accept(TOKEN_SEMICOLON); -} - -/* Table = "table", ID, [Params], "{", "switch", [ "(", Expr, ")" ], {TableCase}, [DefaultCase], "}", ";" ; - - DefaultCase = "default", ":", Expression", ";" ; - */ -static void -parse_table(npl_table_t *t) -{ - accept(TOKEN_TABLE); - t->id = accept_id(); - if (is_params()) - parse_params(&t->params); - - accept(TOKEN_LCURLY); - { - struct npl_table_case **ptr; - - accept(TOKEN_SWITCH); - if (is_token_accept(TOKEN_LPAREN)) { - t->switch_expr = xparse_expression(); - accept(TOKEN_RPAREN); - } - - accept(TOKEN_LCURLY); - - ptr = &(t->cases); - while (is_token_accept(TOKEN_CASE)) { - struct npl_table_case *cur; - - cur = *ptr = xnew(struct npl_table_case); - ptr = &(cur->next); - - parse_expression(&(cur->e)); - accept(TOKEN_COLON); - - while (is_token_accept(TOKEN_CASE)) { - cur = *ptr = xnew(struct npl_table_case); - ptr = &(cur->next); - - parse_expression(&(cur->e)); - accept(TOKEN_COLON); - } - cur->return_expr = xparse_expression(); - accept(TOKEN_SEMICOLON); - } - *ptr = NULL; - - if (is_token_accept(TOKEN_DEFAULT)) { - accept(TOKEN_COLON); - t->default_expr = xparse_expression(); - accept(TOKEN_SEMICOLON); - } - accept(TOKEN_RCURLY); - - } - accept(TOKEN_RCURLY); - is_token_accept(TOKEN_SEMICOLON); -} - -static int -is_type(void) -{ - return - is_token(TOKEN_DECIMAL) || - is_token(TOKEN_NUMBER) || - is_token(TOKEN_TIME) || - is_token(TOKEN_UNSIGNED_NUMBER); -} - -/* Type = BasicType, ID, [Params], "{", {TypeAttr}, "}" ; - - BasicType = "Decimal" | "Number" | "Time" | "UnsignedNumber" ; - - TypeAttr = AttrName, "=", Expression ; - - AttrName = "ByteOrder" | "DisplayFormat" | "Size" ; - */ -static void -parse_type(npl_type_t *t) -{ - if (is_token_accept(TOKEN_DECIMAL)) - t->type = FIELD_DECIMAL; - else if (is_token_accept(TOKEN_NUMBER)) - t->type = FIELD_NUMBER; - else if (is_token_accept(TOKEN_TIME)) - t->type = FIELD_TIME; - else if (is_token_accept(TOKEN_UNSIGNED_NUMBER)) - t->type = FIELD_UNSIGNED_NUMBER; - else - nomatch(); - - t->id = accept_id(); - if (is_params()) - parse_params(&t->params); - accept(TOKEN_LCURLY); - - while (!is_token(TOKEN_RCURLY)) { - npl_expression_t **ptr; - - if (is_token_accept(TOKEN_BYTE_ORDER)) - ptr = &t->byte_order; - else if (is_token_accept(TOKEN_DISPLAY_FORMAT)) - ptr = &t->display_format; - else if (is_token_accept(TOKEN_SIZE)) - ptr = &t->size; - else - nomatch(); -#if 0 - if (*ptr) - fprintf(stdout, "already got %s attr!\n", str); -#endif - accept(TOKEN_ASSIGN); - *ptr = xparse_expression(); - - if (is_token_accept(TOKEN_COMMA)) - { } - else if (is_token_accept(TOKEN_SEMICOLON)) - { } - } - accept(TOKEN_RCURLY); -} - -/* Const = "const", ID, "=", Expression, ";" ; */ -static void -parse_const(npl_const_t *c) -{ - accept(TOKEN_CONST); - c->id = accept_id(); - accept(TOKEN_ASSIGN); - parse_expression(&c->expr); - accept(TOKEN_SEMICOLON); -} - -/* Declaration = Attributes - | Struct - | Table - | Const - | Protocol - | Type - | ( "include", STR ) - ; - */ -static void -parse_decl(npl_decl_t *d) -{ - parse_all_attributes(&d->attr_list); - - if (is_token(TOKEN_STRUCT)) { - d->type = DECL_STRUCT; - parse_struct(&d->s.data, 0); - - } else if (is_token(TOKEN_TABLE)) { - d->type = DECL_TABLE; - parse_table(&d->t.data); - - } else if (is_token(TOKEN_CONST)) { - d->type = DECL_CONST; - parse_const(&d->c.data); - - } else if (is_token(TOKEN_PROTOCOL)) { - d->type = DECL_PROTOCOL; - parse_protocol(&d->p.data); - - } else if (is_type()) { - d->type = DECL_TYPE; - parse_type(&d->ty.data); - - } else if (is_token_accept(TOKEN_INCLUDE)) { - d->type = DECL_INCLUDE; - d->i.file = accept_str(); /* XXX, it's C-escaped */ /* XXX, unix / vs dos \\ */ - - } else - nomatch(); -} - -/* NPL = { Declaration } ; */ -static void -parse_npl(npl_code_t *code) -{ - struct _npl_decl_list **ptr = &(code->decls); - - while (!is_token_accept(TOKEN_EOF)) { - struct _npl_decl_list *cur = xnew(struct _npl_decl_list); - - *ptr = cur; - ptr = &(cur->next); - - parse_decl(&cur->d); - } - *ptr = NULL; -} - -int -npl_parse_file(npl_code_t *code, FILE *f, const char *filename) -{ - volatile int parse_ok = 0; - - yyfilename = filename; - yyin = f; - - if (!setjmp(parser_exception)) { - next_token(); - parse_npl(code); - parse_ok = 1; - } - - yylex_destroy(); - - return (parse_ok == 1); -} - diff --git a/tools/npl/xmem.h b/tools/npl/xmem.h deleted file mode 100644 index 79e66859ab..0000000000 --- a/tools/npl/xmem.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright 2012-2013, Jakub Zawadzki <darkjames-ws@darkjames.pl> - * - * SPDX-License-Identifier: GPL-2.0-or-later - */ - -#ifndef _X_MEM_H -#define _X_MEM_H - -#include <stdlib.h> - -static void oom_killer(void) { - fprintf(stderr, "\n\n !!! Out of memory !!!\n\n"); - abort(); -} - -static inline void *xmalloc(size_t s) { void *ptr = malloc(s); if (!ptr) oom_killer(); return memset(ptr, 0x00, s); } -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 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)) - -#endif |