
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.kisky@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