From 84cf34938294e404fd7e9ebe1a630fe868ae22da Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Mon, 15 Apr 2013 00:36:36 +0200 Subject: expr: fix concat expression type propagation Dynamically instantiate a data type to represent all types of a concatenation and use that for type propagation. --- src/datatype.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) (limited to 'src/datatype.c') diff --git a/src/datatype.c b/src/datatype.c index e87de418..3a2f19d8 100644 --- a/src/datatype.c +++ b/src/datatype.c @@ -23,6 +23,7 @@ #include static const struct datatype *datatypes[TYPE_MAX + 1] = { + [TYPE_INVALID] = &invalid_type, [TYPE_VERDICT] = &verdict_type, [TYPE_BITMASK] = &bitmask_type, [TYPE_INTEGER] = &integer_type, @@ -642,3 +643,39 @@ const struct datatype time_type = { .basetype = &integer_type, .print = time_type_print, }; + +static struct error_record *concat_type_parse(const struct expr *sym, + struct expr **res) +{ + return error(&sym->location, "invalid data type, expected %s", + sym->dtype->desc); +} + +const struct datatype *concat_type_alloc(const struct expr *expr) +{ + struct datatype *dtype; + struct expr *i; + char desc[256] = "concatenation of "; + unsigned int type = 0; + + list_for_each_entry(i, &expr->expressions, list) { + if (type != 0) + strncat(desc, ", ", sizeof(desc) - strlen(desc) - 1); + strncat(desc, i->dtype->desc, sizeof(desc) - strlen(desc) - 1); + + type <<= 8; + type |= i->dtype->type; + } + + dtype = xzalloc(sizeof(*dtype)); + dtype->type = type; + dtype->desc = xstrdup(desc); + dtype->parse = concat_type_parse; + + return dtype; +} + +void concat_type_destroy(const struct datatype *dtype) +{ + xfree(dtype); +} -- cgit v1.2.3