Clear errno before using errcheck() to avoid spurious errors. (#80)
The errcheck() function treats an errno of ERANGE or EDOM as something to report, so make sure errno is set to zero before invoking a function to check so that a previous such errno value won't result in a false positive. This could happen simply due to input line fields that looked enough like floating-point input to trigger ERANGE. Reported by Jordan Geoghegan, fix from Philip Guenther.
This commit is contained in:
parent
754cf93645
commit
b2de1c4ee7
21
run.c
21
run.c
|
@ -25,6 +25,7 @@ THIS SOFTWARE.
|
|||
#define DEBUG
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <wchar.h>
|
||||
#include <wctype.h>
|
||||
#include <fcntl.h>
|
||||
|
@ -1072,8 +1073,10 @@ Cell *arith(Node **a, int n) /* a[0] + a[1], etc. also -a[0] */
|
|||
case POWER:
|
||||
if (j >= 0 && modf(j, &v) == 0.0) /* pos integer exponent */
|
||||
i = ipow(i, (int) j);
|
||||
else
|
||||
else {
|
||||
errno = 0;
|
||||
i = errcheck(pow(i, j), "pow");
|
||||
}
|
||||
break;
|
||||
default: /* can't happen */
|
||||
FATAL("illegal arithmetic operator %d", n);
|
||||
|
@ -1166,8 +1169,10 @@ Cell *assign(Node **a, int n) /* a[0] = a[1], a[0] += a[1], etc. */
|
|||
case POWEQ:
|
||||
if (yf >= 0 && modf(yf, &v) == 0.0) /* pos integer exponent */
|
||||
xf = ipow(xf, (int) yf);
|
||||
else
|
||||
else {
|
||||
errno = 0;
|
||||
xf = errcheck(pow(xf, yf), "pow");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
FATAL("illegal assignment operator %d", n);
|
||||
|
@ -1589,13 +1594,19 @@ Cell *bltin(Node **a, int n) /* builtin functions. a[0] is type, a[1] is arg lis
|
|||
u = strlen(getsval(x));
|
||||
break;
|
||||
case FLOG:
|
||||
u = errcheck(log(getfval(x)), "log"); break;
|
||||
errno = 0;
|
||||
u = errcheck(log(getfval(x)), "log");
|
||||
break;
|
||||
case FINT:
|
||||
modf(getfval(x), &u); break;
|
||||
case FEXP:
|
||||
u = errcheck(exp(getfval(x)), "exp"); break;
|
||||
errno = 0;
|
||||
u = errcheck(exp(getfval(x)), "exp");
|
||||
break;
|
||||
case FSQRT:
|
||||
u = errcheck(sqrt(getfval(x)), "sqrt"); break;
|
||||
errno = 0;
|
||||
u = errcheck(sqrt(getfval(x)), "sqrt");
|
||||
break;
|
||||
case FSIN:
|
||||
u = sin(getfval(x)); break;
|
||||
case FCOS:
|
||||
|
|
Loading…
Reference in New Issue