>-----Original Message----- >From: Troy Kisky [mailto:troy.ki...@boundarydevices.com] >Sent: Wednesday, November 28, 2012 9:32 AM >To: sba...@denx.de >Cc: dirk.be...@googlemail.com; u-boot@lists.denx.de; Liu Hui-R64343; >feste...@gmail.com; Troy Kisky >Subject: [PATCH V4 11/11] parse_helper: add expression evaluation > >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>
Acked-by: Jason Liu <r64...@freescale.com> >--- > tools/parse_helper.c | 172 >+++++++++++++++++++++++++++++++++++++++++++++++--- > 1 file changed, 162 insertions(+), 10 deletions(-) > >diff --git a/tools/parse_helper.c b/tools/parse_helper.c index >0a5c5f6..50be832 100644 >--- a/tools/parse_helper.c >+++ b/tools/parse_helper.c >@@ -97,20 +97,172 @@ int ph_skip_comma(struct parse_helper *ph) > } > } > >+static const char precedence[] = { >+ /* ( + - * / & ^ | ) */ >+ 0, 2, 2, 1, 1, 3, 4, 5, 6 >+}; >+static const char unary_operations[] = "(+-"; static const char >+binary_operations[] = " +-*/&^|)"; >+ >+static 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); >+} >+ >+static int find_op(char c, const 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])) >+ > int ph_get_value(struct parse_helper *ph, 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 (ph_skip_separators(ph)) >- return -1; >- errno = 0; >- value = strtoul(ph->p, &endptr, 16); >- if (errno || (ph->p == endptr)) >- return -1; >- *pval = value; >- ph->p = endptr; >- return 0; >+ p = ph->p; >+ for (;;) { >+ char c; >+ int i, j; >+ const char *ops = unary ? unary_operations : >binary_operations; >+ >+ if (unary) { >+ ph->p = p; >+ if (ph_skip_separators(ph)) >+ return -1; >+ p = ph->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)) { >+ ph->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; >+ } >+ ph->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; >+ } > } > > /* >-- >1.7.9.5 > _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot