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

Reply via email to