aboutsummaryrefslogtreecommitdiff
path: root/libbb/arith.c
diff options
context:
space:
mode:
Diffstat (limited to 'libbb/arith.c')
-rw-r--r--libbb/arith.c33
1 files changed, 23 insertions, 10 deletions
diff --git a/libbb/arith.c b/libbb/arith.c
index c7a3cf98b..04c45ec3d 100644
--- a/libbb/arith.c
+++ b/libbb/arith.c
@@ -119,20 +119,26 @@ static short arith_apply(operator op, long *numstack, long **numstackptr)
119 NUMPTR[-1] = (NUMPTR[-1] <= *NUMPTR); 119 NUMPTR[-1] = (NUMPTR[-1] <= *NUMPTR);
120 else if (op == TOK_MUL) 120 else if (op == TOK_MUL)
121 NUMPTR[-1] *= *NUMPTR; 121 NUMPTR[-1] *= *NUMPTR;
122 else if (op == TOK_DIV) 122 else if (op == TOK_DIV) {
123 if(*NUMPTR==0)
124 return -2;
123 NUMPTR[-1] /= *NUMPTR; 125 NUMPTR[-1] /= *NUMPTR;
124 else if (op == TOK_REM) 126 }
127 else if (op == TOK_REM) {
128 if(*NUMPTR==0)
129 return -2;
125 NUMPTR[-1] %= *NUMPTR; 130 NUMPTR[-1] %= *NUMPTR;
131 }
126 else if (op == TOK_ADD) 132 else if (op == TOK_ADD)
127 NUMPTR[-1] += *NUMPTR; 133 NUMPTR[-1] += *NUMPTR;
128 else if (op == TOK_SUB) 134 else if (op == TOK_SUB)
129 NUMPTR[-1] -= *NUMPTR; 135 NUMPTR[-1] -= *NUMPTR;
130 } 136 }
131 return 0; 137 return 0;
132err: return(1); 138err: return(-1);
133} 139}
134 140
135extern long arith (const char *startbuf) 141extern long arith (const char *startbuf, int *errcode)
136{ 142{
137 register char arithval; 143 register char arithval;
138 const char *expr = startbuf; 144 const char *expr = startbuf;
@@ -142,8 +148,9 @@ extern long arith (const char *startbuf)
142 unsigned char prec; 148 unsigned char prec;
143 149
144 long *numstack, *numstackptr; 150 long *numstack, *numstackptr;
145
146 operator *stack = alloca(datasizes * sizeof(operator)), *stackptr = stack; 151 operator *stack = alloca(datasizes * sizeof(operator)), *stackptr = stack;
152
153 *errcode = 0;
147 numstack = alloca((datasizes/2+1)*sizeof(long)), numstackptr = numstack; 154 numstack = alloca((datasizes/2+1)*sizeof(long)), numstackptr = numstack;
148 155
149 while ((arithval = *expr)) { 156 while ((arithval = *expr)) {
@@ -163,7 +170,8 @@ extern long arith (const char *startbuf)
163 op = *--stackptr; 170 op = *--stackptr;
164 if (op == TOK_LPAREN) 171 if (op == TOK_LPAREN)
165 goto prologue; 172 goto prologue;
166 if(ARITH_APPLY(op)) goto err; 173 *errcode = ARITH_APPLY(op);
174 if(*errcode) return *errcode;
167 } 175 }
168 goto err; /* Mismatched parens */ 176 goto err; /* Mismatched parens */
169 } if (arithval == '|') { 177 } if (arithval == '|') {
@@ -231,17 +239,22 @@ extern long arith (const char *startbuf)
231 239
232 prec = PREC(op); 240 prec = PREC(op);
233 if (prec != UNARYPREC) 241 if (prec != UNARYPREC)
234 while (stackptr != stack && PREC(stackptr[-1]) >= prec) 242 while (stackptr != stack && PREC(stackptr[-1]) >= prec) {
235 if(ARITH_APPLY(*--stackptr)) goto err; 243 *errcode = ARITH_APPLY(*--stackptr);
244 if(*errcode) return *errcode;
245 }
236 *stackptr++ = op; 246 *stackptr++ = op;
237 lasttok = op; 247 lasttok = op;
238prologue: ++expr; 248prologue: ++expr;
239 } /* yay */ 249 } /* yay */
240 250
241 while (stackptr != stack) 251 while (stackptr != stack) {
242 if(ARITH_APPLY(*--stackptr)) goto err; 252 *errcode = ARITH_APPLY(*--stackptr);
253 if(*errcode) return *errcode;
254 }
243 if (numstackptr != numstack+1) { 255 if (numstackptr != numstack+1) {
244err: 256err:
257 *errcode = -1;
245 return -1; 258 return -1;
246 /* NOTREACHED */ 259 /* NOTREACHED */
247 } 260 }