Patch from vodz:
[oweals/busybox.git] / libbb / arith.c
index d79501cc46cf71dd10484426c59117fcbeec3ea2..3e107126accc261ce24fdbe607be5a5b5db682bc 100644 (file)
@@ -140,8 +140,7 @@ typedef char operator;
 #define TOK_REM tok_decl(10,2)
 
 /* For now all unary operators have the same precedence, and that's used to
- * identify them as unary operators
- */
+ * identify them as unary operators */
 #define UNARYPREC 14
 #define TOK_BNOT tok_decl(UNARYPREC,0)
 #define TOK_NOT tok_decl(UNARYPREC,1)
@@ -157,82 +156,68 @@ 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
- */
+ * binary operator will pop two arguments and push a result */
 static short arith_apply(operator    op, long *numstack, long **numstackptr)
 {
        long numptr_val;
        long *NUMPTR_M1;
 
-       /* There is no operator that can work without arguments */
-       if (NUMPTR == numstack) {
-               goto err;
-       }
-
+       if (NUMPTR == numstack) goto err; /* There is no operator that can work
+                                                                                without arguments */
        NUMPTR_M1 = NUMPTR - 1;
-       if (op == TOK_UMINUS) {
+       if (op == TOK_UMINUS)
                *NUMPTR_M1 *= -1;
-       } else if (op == TOK_NOT) {
+       else if (op == TOK_NOT)
                *NUMPTR_M1 = !(*NUMPTR_M1);
-       } else if (op == TOK_BNOT) {
+       else if (op == TOK_BNOT)
                *NUMPTR_M1 = ~(*NUMPTR_M1);
-       else if (op != TOK_UPLUS) {
+       else if (op != TOK_UPLUS) {
                /* Binary operators */
-
-               /* ... and binary operators need two arguments */
-               if (NUMPTR_M1 == numstack) {
-                       goto err;
-               }
-               /* ... and they pop one */
-               numptr_val = *--NUMPTR;
-
+       if (NUMPTR_M1 == numstack) goto err; /* ... and binary operators need two
+                                                                                  arguments */
+       numptr_val = *--NUMPTR;         /* ... and they pop one */
                NUMPTR_M1 = NUMPTR - 1;
-
-               if (op == TOK_BOR) {
+       if (op == TOK_BOR)
                        *NUMPTR_M1 |= numptr_val;
-               } else if (op == TOK_OR) {
+       else if (op == TOK_OR)
                        *NUMPTR_M1 = numptr_val || *NUMPTR_M1;
-               } else if (op == TOK_BAND) {
+       else if (op == TOK_BAND)
                        *NUMPTR_M1 &= numptr_val;
-               } else if (op == TOK_AND) {
+       else if (op == TOK_AND)
                        *NUMPTR_M1 = *NUMPTR_M1 && numptr_val;
-               } else if (op == TOK_EQ) {
+       else if (op == TOK_EQ)
                        *NUMPTR_M1 = (*NUMPTR_M1 == numptr_val);
-               } else if (op == TOK_NE) {
+       else if (op == TOK_NE)
                        *NUMPTR_M1 = (*NUMPTR_M1 != numptr_val);
-               } else if (op == TOK_GE) {
+       else if (op == TOK_GE)
                        *NUMPTR_M1 = (*NUMPTR_M1 >= numptr_val);
-               } else if (op == TOK_RSHIFT) {
+       else if (op == TOK_RSHIFT)
                        *NUMPTR_M1 >>= numptr_val;
-               } else if (op == TOK_LSHIFT) {
+       else if (op == TOK_LSHIFT)
                        *NUMPTR_M1 <<= numptr_val;
-               } else if (op == TOK_GT) {
+       else if (op == TOK_GT)
                        *NUMPTR_M1 = (*NUMPTR_M1 > numptr_val);
-               } else if (op == TOK_LT) {
+       else if (op == TOK_LT)
                        *NUMPTR_M1 = (*NUMPTR_M1 < numptr_val);
-               } else if (op == TOK_LE) {
+       else if (op == TOK_LE)
                        *NUMPTR_M1 = (*NUMPTR_M1 <= numptr_val);
-               } else if (op == TOK_MUL) {
+       else if (op == TOK_MUL)
                        *NUMPTR_M1 *= numptr_val;
-               } else if (op == TOK_ADD) {
+       else if (op == TOK_ADD)
                        *NUMPTR_M1 += numptr_val;
-               } else if (op == TOK_SUB) {
+       else if (op == TOK_SUB)
                        *NUMPTR_M1 -= numptr_val;
-               }
-               /* zero divisor check */
-               else if (numptr_val == 0) {
+       else if(numptr_val==0)          /* zero divisor check */
                        return -2;
-               } else if (op == TOK_DIV) {
+       else if (op == TOK_DIV)
                        *NUMPTR_M1 /= numptr_val;
-               } else if (op == TOK_REM) {
+       else if (op == TOK_REM)
                        *NUMPTR_M1 %= numptr_val;
-               }
                /* WARNING!!!  WARNING!!!  WARNING!!! */
                /* Any new operators should be added BEFORE the zero divisor check! */
        }
        return 0;
-  err:
-       return (-1);
+err: return(-1);
 }
 
 static const char endexpression[] = ")";
@@ -242,7 +227,7 @@ static const char op_char[] = "!<>=|&*/%~()+-";
 static const char op_token[] = {
        /* paired with equal */
        TOK_NE, TOK_LE, TOK_GE,
-       /* paired with self -- note: ! is special-cased below */
+       /* paired with self -- note: ! is special-cased below*/
        TOK_ERROR, TOK_LSHIFT, TOK_RSHIFT, TOK_EQ, TOK_OR, TOK_AND,
        /* singles */
        TOK_NOT, TOK_LT, TOK_GT, TOK_ERROR, TOK_BOR, TOK_BAND,
@@ -253,33 +238,34 @@ static const char op_token[] = {
 #define NUM_PAIR_EQUAL  3
 #define NUM_PAIR_SAME   6
 
-extern long arith(const char *expr, int *errcode)
+extern long arith (const char *expr, int *errcode)
 {
        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 + 1) / 2) * sizeof(long));
-       long *numstackptr = numstack;
-
+       long *numstack = alloca(((datasizes)/2)*sizeof(long)),
+               *numstackptr = numstack;
        /* Stack of operator tokens */
-       operator * stack = alloca((datasizes + 1) * sizeof(operator));
-       operator * stackptr = stack;
+       operator *stack = alloca((datasizes) * sizeof(operator)),
+               *stackptr = stack;
 
-       /* start off with a left paren */
-       *stackptr++ = lasttok = TOK_LPAREN;
+       *numstack = 0;
+       *stackptr++ = lasttok = TOK_LPAREN;     /* start off with a left paren */
 
   loop:
        if ((arithval = *expr) == 0) {
-               /* Null expression. */
-               if (p == endexpression) {
-                       return (*errcode = 0);
+               if (p == endexpression) { /* Null expression. */
+                       *errcode = 0;
+                       return *numstack;
                }
 
                /* This is only reached after all tokens have been extracted from the
@@ -292,7 +278,7 @@ extern long arith(const char *expr, int *errcode)
                        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 */
+               if (numstackptr != numstack+1) {/* ... but if there isn't, it's bad */
                  err:
                        return (*errcode = -1);
                        /* NOTREACHED */
@@ -300,12 +286,10 @@ extern long arith(const char *expr, int *errcode)
                return *numstack;
        } else {
                /* Continue processing the expression.  */
-               /* Skip whitespace */
                if (isspace(arithval)) {
-                       goto prologue;
+                       goto prologue;          /* Skip whitespace */
                }
-               /* isdigit ? */
-               if ((unsigned) arithval - '0' <= 9) {
+               if ((unsigned)arithval-'0' <= 9) /* isdigit */ {
                        *numstackptr++ = strtol(expr, (char **) &expr, 10);
                        lasttok = TOK_NUM;
                        goto loop;
@@ -315,21 +299,20 @@ extern long arith(const char *expr, int *errcode)
                        goto err;
                }
 #else
-               for (p = op_char; *p != arithval; p++) {
+           for ( p=op_char ; *p != arithval ; p++ ) {
                        if (!*p) {
                                goto err;
                        }
                }
 #endif
-               p = op_token + (int) (p - op_char);
+               p = op_token + (int)(p - op_char);
                ++expr;
                if ((p >= op_token + NUM_PAIR_EQUAL) || (*expr != '=')) {
                        p += NUM_PAIR_EQUAL;
                        if ((p >= op_token + NUM_PAIR_SAME + NUM_PAIR_EQUAL)
                                || (*expr != arithval) || (arithval == '!')) {
                                --expr;
-                               /* single = */
-                               if (arithval == '=') {
+                               if (arithval == '=') { /* single = */
                                        goto err;
                                }
                                p += NUM_PAIR_SAME;
@@ -338,11 +321,9 @@ extern long arith(const char *expr, int *errcode)
                                 * a number, since it evaluates to one). Think about it.
                                 * It makes sense. */
                                if ((lasttok != TOK_NUM)
-                                       && (p >=
-                                               (op_token + NUM_PAIR_SAME + NUM_PAIR_EQUAL +
-                                                sizeof(op_char) - 2))) {
-                                       /* Unary plus or minus */
-                                       p += 2;
+                                       && (p >= op_token + NUM_PAIR_SAME + NUM_PAIR_EQUAL
+                                               + sizeof(op_char) - 2)) {
+                                       p += 2; /* Unary plus or minus */
                                }
                        }
                }
@@ -358,11 +339,8 @@ extern long arith(const char *expr, int *errcode)
                /* Left paren is given the lowest priority so it will never be
                 * "applied" in this way */
                prec = PREC(op);
-
-               /* not left paren or unary */
-               if ((prec > 0) && (prec != UNARYPREC)) {
-                       /* binary op must be preceded by a num */
-                       if (lasttok != TOK_NUM) {
+               if ((prec > 0) && (prec != UNARYPREC)) { /* not left paren or unary */
+                       if (lasttok != TOK_NUM) { /* binary op must be preceded by a num */
                                goto err;
                        }
                        while (stackptr != stack) {
@@ -372,10 +350,7 @@ extern long arith(const char *expr, int *errcode)
                                         * tokens and apply them */
                                        if (stackptr[-1] == TOK_LPAREN) {
                                                --stackptr;
-
-                                               /* Any operator directly after a */
-                                               lasttok = TOK_NUM;
-
+                                               lasttok = TOK_NUM; /* Any operator directly after a */
                                                /* close paren should consider itself binary */
                                                goto prologue;
                                        }
@@ -383,9 +358,7 @@ extern long arith(const char *expr, int *errcode)
                                        break;
                                }
                                *errcode = ARITH_APPLY(*--stackptr);
-                               if (*errcode) {
-                                       return *errcode;
-                               }
+                               if(*errcode) return *errcode;
                        }
                        if (op == TOK_RPAREN) {
                                goto err;