On 22/09/2012 04:39, Troy Kisky wrote: > Basic expressions with order precedence is > now supported. > ie. (----3 + ((1+2*3)/--2 + --5 *(8/4))) is 16. > > Signed-off-by: Troy Kisky <troy.ki...@boundarydevices.com> > ---
Hi Troy, > tools/imximage.c | 172 > ++++++++++++++++++++++++++++++++++++++++++++++++++---- > 1 file changed, 162 insertions(+), 10 deletions(-) > > diff --git a/tools/imximage.c b/tools/imximage.c > index 1e120354..2c5a622 100644 I have some general considerations. First, if you plan to add support for expression evaluation, this feature should be available generally for mkimage, that means also other processors / architecture can profit of it. It should be moved away from imximage.c code. Then, you want also let that the preprocesso can parse the imximage code. I can imagine that in such terms it could be then possible to define in imximage.cfg something like: #define DDR_VAL (1 <<17 | 3 << 7) #define ADDRESS 0x0x53something DATA 4 ADDRESS DDR_VAL Else, why do we need the power of C preprocessor ? If this is true, can you explain us which is the use case using the C preprocessor and which is the one for the expression evaluator ? And why do we need both ? > --- a/tools/imximage.c > +++ b/tools/imximage.c > @@ -380,20 +380,172 @@ char *grab_token(char *dest, int size, char *src) > return src; > } > > +char precedence[] = { > + /* ( + - * / & ^ | ) */ > + 0, 2, 2, 1, 1, 3, 4, 5, 6 > +}; > +char unary_operations[] = "(+-"; > +char binary_operations[] = " +-*/&^|)"; > + > +uint32_t do_func(uint32_t val1, uint32_t val2, int op) > +{ > + switch (op) { > + case 1: > + return val1 + val2; > + case 2: > + return val1 - val2; > + case 3: > + return val1 * val2; > + case 4: > + return val1 / val2; > + case 5: > + return val1 & val2; > + case 6: > + return val1 ^ val2; > + case 7: > + return val1 | val2; > + } > + fprintf(stderr, "Error: in func %s: val1=%d val2=%d op = %d\n", > + __func__, val1, val2, op); > + exit(EXIT_FAILURE); > +} > + > +int find_op(char c, char *p) > +{ > + int i; > + for (i = 0; ; i++) { > + if (c == p[i]) > + return i; > + if (!p[i]) > + break; > + } > + return -1; > +} > + > +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) > + > static uint32_t get_cfg_value(struct data_src *ds, uint32_t *pval) > { > char *endptr; > - uint32_t value; > + int op_i = 0; > + int val_i = 0; > + unsigned char op[16]; > + uint32_t val[16]; > + int unary = 1; > + char *p; > > - if (skip_separators(ds)) > - return -1; > - errno = 0; > - value = strtoul(ds->p, &endptr, 16); > - if (errno || (ds->p == endptr)) > - return -1; > - *pval = value; > - ds->p = endptr; > - return 0; > + p = ds->p; > + for (;;) { > + char c; > + int i, j; > + char *ops = unary ? unary_operations : binary_operations; > + > + if (unary) { > + ds->p = p; > + if (skip_separators(ds)) > + return -1; > + p = ds->p; > + c = *p; > + } else { > + for (;;) { > + c = *p; > + if ((c != ' ') && (c != '\t')) > + break; > + p++; > + } > + } > + i = find_op(c, ops); > + debug("%d,%c,%d:%s\n", i, c, unary, p); > + if ((i < 0) && unary) { > + if (val_i >= ARRAY_SIZE(val)) > + return -1; > + errno = 0; > + val[val_i++] = strtoul(p, &endptr, 16); > + if (errno || (p == endptr)) { > + ds->p = p; > + return -1; > + } > + p = endptr; > + unary = 0; > + debug("val[%d]=%x,%d,%d\n", val_i - 1, val[val_i - 1], > + op_i, val_i); > +do_unary: > + while (op_i) { > + j = op[op_i - 1]; > + if (!(j & 0x80)) > + break; > + op_i--; > + val[val_i - 1] = do_func(0, > + val[val_i - 1], j & 0x7f); > + debug("un:%d,%x,%d,%d\n", val[val_i - 1], j, > + op_i, val_i); > + } > + continue; > + } > + if (i < 0) { > + c = 0; > + i = 8; > + } else { > + p++; > + } > + if (c == '(') { > + if (op_i >= ARRAY_SIZE(op)) > + return -1; > + op[op_i++] = i; > + debug("op[%d]=%x,%d,%d\n", op_i - 1, op[op_i - 1], > + op_i, val_i); > + unary = 1; > + continue; > + } > + for (;;) { > + if (!op_i || unary) > + break; > + j = op[op_i - 1]; > + if (j == 0) { > + if (c == ')') { > + op_i--; > + goto do_unary; > + } > + break; > + } > + if ((j & 0x80)) { > + op_i--; > + val[val_i - 1] = do_func(0, > + val[val_i - 1], j & 0x7f); > + debug("unary:%d,%x\n", val[val_i - 1], j); > + continue; > + } > + if (precedence[i] < precedence[j]) > + break; > + if (val_i < 2) > + return -1; > + op_i--; > + val[val_i - 2] = do_func(val[val_i - 2], > + val[val_i - 1], j); > + val_i--; > + debug("binary:%d,%x,%d,%d\n", val[val_i - 1], j, > + op_i, val_i); > + } > + if (c == ')') { > + fprintf(stderr, "Error: unmatched parenthesis\n"); > + return -1; > + } > + if (i == 8) { > + if ((op_i != 0) || (val_i != 1)) { > + fprintf(stderr, "Error: syntax %d %d\n", > + op_i, val_i); > + return -1; > + } > + ds->p = p; > + *pval = val[0]; > + return 0; > + } > + if (op_i >= ARRAY_SIZE(op)) > + return -1; > + op[op_i++] = i | (unary << 7); > + debug("op[%d]=%x,%d,%d\n", op_i - 1, op[op_i - 1], op_i, val_i); > + unary = 1; > + } > } Best regards, Stefano Babic -- ===================================================================== DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sba...@denx.de ===================================================================== _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot