@@ -115,6 +115,7 @@ enum datatype_flags {
* @byteorder: byteorder of type (non-basetypes only)
* @flags: flags
* @size: type size (fixed sized non-basetypes only)
+ * @subtypes: number of subtypes (concat type)
* @name: type name
* @desc: type description
* @basetype: basetype for subtypes, determines type compatibilty
@@ -128,6 +129,7 @@ struct datatype {
enum byteorder byteorder;
unsigned int flags;
unsigned int size;
+ unsigned int subtypes;
const char *name;
const char *desc;
const struct datatype *basetype;
@@ -928,10 +928,10 @@ const struct datatype *concat_type_alloc(const struct expr *expr)
struct expr *i;
char desc[256] = "concatenation of (";
char name[256] = "";
- unsigned int type = 0, size = 0;
+ unsigned int type = 0, size = 0, subtypes = 0;
list_for_each_entry(i, &expr->expressions, list) {
- if (size != 0) {
+ if (subtypes != 0) {
strncat(desc, ", ", sizeof(desc) - strlen(desc) - 1);
strncat(name, " . ", sizeof(name) - strlen(name) - 1);
}
@@ -940,13 +940,15 @@ const struct datatype *concat_type_alloc(const struct expr *expr)
type <<= 8;
type |= i->dtype->type;
- size++;
+ size += i->dtype->size;
+ subtypes++;
}
strncat(desc, ")", sizeof(desc) - strlen(desc) - 1);
dtype = dtype_alloc();
dtype->type = type;
dtype->size = size;
+ dtype->subtypes = subtypes;
dtype->name = xstrdup(name);
dtype->desc = xstrdup(desc);
dtype->parse = concat_type_parse;
@@ -605,10 +605,10 @@ static int expr_evaluate_concat(struct eval_ctx *ctx, struct expr **expr)
{
const struct datatype *dtype = ctx->ectx.dtype, *tmp;
unsigned int type = dtype ? dtype->type : 0;
- int off = dtype ? dtype->size: 0;
+ int off = dtype ? dtype->subtypes : 0;
unsigned int flags = EXPR_F_CONSTANT | EXPR_F_SINGLETON;
struct expr *i, *next;
- unsigned int n;
+ unsigned int n, len = 0;
n = 1;
list_for_each_entry_safe(i, next, &(*expr)->expressions, list) {
@@ -624,11 +624,13 @@ static int expr_evaluate_concat(struct eval_ctx *ctx, struct expr **expr)
return -1;
flags &= i->flags;
+ len += i->len;
n++;
}
(*expr)->flags |= flags;
(*expr)->dtype = concat_type_alloc(*expr);
+ (*expr)->len = len;
if (off > 0)
return expr_error(ctx->msgs, *expr,
Using the size is confusing since it usually holds the size of the data. Add a new "subtypes" member, which holds the number of datatypes the concat type is made of. Signed-off-by: Patrick McHardy <kaber@trash.net> --- include/datatype.h | 2 ++ src/datatype.c | 8 +++++--- src/evaluate.c | 6 ++++-- 3 files changed, 11 insertions(+), 5 deletions(-)