X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=libbb%2Farith.c;h=3e107126accc261ce24fdbe607be5a5b5db682bc;hb=8ae4cab4a85eea297a0b8ea9aa65c3c23b0a664b;hp=362f7bb2b6dac490e8e0eeebb52ae13e435a6fe6;hpb=6a9d1f652b20f53dfd64e260d2796d55ad973c98;p=oweals%2Fbusybox.git diff --git a/libbb/arith.c b/libbb/arith.c index 362f7bb2b..3e107126a 100644 --- a/libbb/arith.c +++ b/libbb/arith.c @@ -26,14 +26,14 @@ * 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; }