use #ifdef CONFIG_* instead of #if CONFIG_*
[oweals/busybox.git] / libbb / arith.c
index 362f7bb2b6dac490e8e0eeebb52ae13e435a6fe6..3e107126accc261ce24fdbe607be5a5b5db682bc 100644 (file)
  * listed in #defines below. Parens, order of operations, and error handling
  * are supported. This code is threadsafe. The exact expression format should
  * be that which POSIX specifies for shells. */
+
 /* The code uses a simple two-stack algorithm. See
  * http://www.onthenet.com.au/~grahamis/int2008/week02/lect02.html
  * for a detailed explaination of the infix-to-postfix algorithm on which
  * this is based (this code differs in that it applies operators immediately
  * to the stack instead of adding them to a queue to end up with an
  * expression). */
+
 /* To use the routine, call it with an expression string and error return
  * pointer */
 
@@ -149,7 +149,7 @@ typedef char operator;
 
 #define TOK_NUM tok_decl(15,0)
 #define TOK_RPAREN tok_decl(15,1)
-#define TOK_ERROR  tok_decl(15,2) /* just a place-holder really */
+#define TOK_ERROR  tok_decl(15,2)      /* just a place-holder really */
 
 #define ARITH_APPLY(op) arith_apply(op, numstack, &numstackptr)
 #define NUMPTR (*numstackptr)
@@ -157,7 +157,7 @@ typedef char operator;
 /* "applying" a token means performing it on the top elements on the integer
  * stack. For a unary operator it will only change the top element, but a
  * binary operator will pop two arguments and push a result */
-static short arith_apply(operator op, long *numstack, long **numstackptr)
+static short arith_apply(operator    op, long *numstack, long **numstackptr)
 {
        long numptr_val;
        long *NUMPTR_M1;
@@ -172,49 +172,49 @@ static short arith_apply(operator op, long *numstack, long **numstackptr)
        else if (op == TOK_BNOT)
                *NUMPTR_M1 = ~(*NUMPTR_M1);
        else if (op != TOK_UPLUS) {
-       /* Binary operators */
+               /* Binary operators */
        if (NUMPTR_M1 == numstack) goto err; /* ... and binary operators need two
                                                                                   arguments */
-       numptr_val = *--NUMPTR;         /* ... and they pop one */
-       NUMPTR_M1 = NUMPTR - 1;
+       numptr_val = *--NUMPTR;         /* ... and they pop one */
+               NUMPTR_M1 = NUMPTR - 1;
        if (op == TOK_BOR)
-               *NUMPTR_M1 |= numptr_val;
+                       *NUMPTR_M1 |= numptr_val;
        else if (op == TOK_OR)
-               *NUMPTR_M1 = numptr_val || *NUMPTR_M1;
+                       *NUMPTR_M1 = numptr_val || *NUMPTR_M1;
        else if (op == TOK_BAND)
-               *NUMPTR_M1 &= numptr_val;
+                       *NUMPTR_M1 &= numptr_val;
        else if (op == TOK_AND)
-               *NUMPTR_M1 = *NUMPTR_M1 && numptr_val;
+                       *NUMPTR_M1 = *NUMPTR_M1 && numptr_val;
        else if (op == TOK_EQ)
-               *NUMPTR_M1 = (*NUMPTR_M1 == numptr_val);
+                       *NUMPTR_M1 = (*NUMPTR_M1 == numptr_val);
        else if (op == TOK_NE)
-               *NUMPTR_M1 = (*NUMPTR_M1 != numptr_val);
+                       *NUMPTR_M1 = (*NUMPTR_M1 != numptr_val);
        else if (op == TOK_GE)
-               *NUMPTR_M1 = (*NUMPTR_M1 >= numptr_val);
+                       *NUMPTR_M1 = (*NUMPTR_M1 >= numptr_val);
        else if (op == TOK_RSHIFT)
-               *NUMPTR_M1 >>= numptr_val;
+                       *NUMPTR_M1 >>= numptr_val;
        else if (op == TOK_LSHIFT)
-               *NUMPTR_M1 <<= numptr_val;
+                       *NUMPTR_M1 <<= numptr_val;
        else if (op == TOK_GT)
-               *NUMPTR_M1 = (*NUMPTR_M1 > numptr_val);
+                       *NUMPTR_M1 = (*NUMPTR_M1 > numptr_val);
        else if (op == TOK_LT)
-               *NUMPTR_M1 = (*NUMPTR_M1 < numptr_val);
+                       *NUMPTR_M1 = (*NUMPTR_M1 < numptr_val);
        else if (op == TOK_LE)
-               *NUMPTR_M1 = (*NUMPTR_M1 <= numptr_val);
+                       *NUMPTR_M1 = (*NUMPTR_M1 <= numptr_val);
        else if (op == TOK_MUL)
-               *NUMPTR_M1 *= numptr_val;
+                       *NUMPTR_M1 *= numptr_val;
        else if (op == TOK_ADD)
-               *NUMPTR_M1 += numptr_val;
+                       *NUMPTR_M1 += numptr_val;
        else if (op == TOK_SUB)
-               *NUMPTR_M1 -= numptr_val;
-       else if(numptr_val==0)          /* zero divisor check */
-               return -2;
+                       *NUMPTR_M1 -= numptr_val;
+       else if(numptr_val==0)          /* zero divisor check */
+                       return -2;
        else if (op == TOK_DIV)
-               *NUMPTR_M1 /= numptr_val;
+                       *NUMPTR_M1 /= numptr_val;
        else if (op == TOK_REM)
-               *NUMPTR_M1 %= numptr_val;
-       /* WARNING!!!  WARNING!!!  WARNING!!! */
-       /* Any new operators should be added BEFORE the zero divisor check! */
+                       *NUMPTR_M1 %= numptr_val;
+               /* WARNING!!!  WARNING!!!  WARNING!!! */
+               /* Any new operators should be added BEFORE the zero divisor check! */
        }
        return 0;
 err: return(-1);
@@ -240,30 +240,32 @@ static const char op_token[] = {
 
 extern long arith (const char *expr, int *errcode)
 {
-       register char arithval;         /* Current character under analysis */
-       operator lasttok, op;
+       register char arithval; /* Current character under analysis */
+       operator    lasttok, op;
        unsigned char prec;
 
        const char *p = endexpression;
 
-       size_t datasizes = strlen(expr);
+       size_t datasizes = strlen(expr) + 2;
 
        /* Stack of integers */
        /* The proof that there can be no more than strlen(startbuf)/2+1 integers
         * in any given correct or incorrect expression is left as an excersize to
         * the reader. */
-       long *numstack = alloca((datasizes/2)*sizeof(long)),
+       long *numstack = alloca(((datasizes)/2)*sizeof(long)),
                *numstackptr = numstack;
        /* Stack of operator tokens */
-       operator *stack = alloca((datasizes+1) * sizeof(operator)),
+       operator *stack = alloca((datasizes) * sizeof(operator)),
                *stackptr = stack;
 
-       *stackptr++ = lasttok = TOK_LPAREN;     /* start off with a left paren */
+       *numstack = 0;
+       *stackptr++ = lasttok = TOK_LPAREN;     /* start off with a left paren */
 
- loop:
 loop:
        if ((arithval = *expr) == 0) {
                if (p == endexpression) { /* Null expression. */
-                       return (*errcode = 0);
+                       *errcode = 0;
+                       return *numstack;
                }
 
                /* This is only reached after all tokens have been extracted from the
@@ -271,13 +273,13 @@ extern long arith (const char *expr, int *errcode)
                 * are to be applied in order. At the end, there should be a final
                 * result on the integer stack */
 
-               if (expr != endexpression + 1) { /* If we haven't done so already, */
+               if (expr != endexpression + 1) {        /* If we haven't done so already, */
                        expr = endexpression;   /* append a closing right paren */
-                       goto loop;                              /* and let the loop process it. */
+                       goto loop;      /* and let the loop process it. */
                }
                /* At this point, we're done with the expression. */
                if (numstackptr != numstack+1) {/* ... but if there isn't, it's bad */
-               err: 
+                 err:
                        return (*errcode = -1);
                        /* NOTREACHED */
                }
@@ -285,7 +287,7 @@ extern long arith (const char *expr, int *errcode)
        } else {
                /* Continue processing the expression.  */
                if (isspace(arithval)) {
-                       goto prologue;          /* Skip whitespace */
+                       goto prologue;          /* Skip whitespace */
                }
                if ((unsigned)arithval-'0' <= 9) /* isdigit */ {
                        *numstackptr++ = strtol(expr, (char **) &expr, 10);
@@ -321,7 +323,7 @@ extern long arith (const char *expr, int *errcode)
                                if ((lasttok != TOK_NUM)
                                        && (p >= op_token + NUM_PAIR_SAME + NUM_PAIR_EQUAL
                                                + sizeof(op_char) - 2)) {
-                                       p += 2; /* Unary plus or minus */
+                                       p += 2; /* Unary plus or minus */
                                }
                        }
                }
@@ -349,7 +351,7 @@ extern long arith (const char *expr, int *errcode)
                                        if (stackptr[-1] == TOK_LPAREN) {
                                                --stackptr;
                                                lasttok = TOK_NUM; /* Any operator directly after a */
-                                                               /* close paren should consider itself binary */
+                                               /* close paren should consider itself binary */
                                                goto prologue;
                                        }
                                } else if (PREC(stackptr[-1]) < prec) {
@@ -366,7 +368,7 @@ extern long arith (const char *expr, int *errcode)
                /* Push this operator to the stack and remember it. */
                *stackptr++ = lasttok = op;
 
-       prologue:
+         prologue:
                ++expr;
                goto loop;
        }