union {
char *s;
- int i;
+ int64_t i;
} u;
};
struct val *tokval;
char **av;
-struct val *make_int __P((int));
+struct val *make_int __P((int64_t));
struct val *make_str __P((char *));
void free_value __P((struct val *));
-int is_integer __P((struct val *, int *));
+int is_integer __P((struct val *, int64_t *));
int to_integer __P((struct val *));
void to_string __P((struct val *));
+int is_null __P((struct val *));
int is_zero_or_null __P((struct val *));
void nexttoken __P((void));
void error __P((void)) __attribute__((__noreturn__));
struct val *
make_int(i)
- int i;
+ int64_t i;
{
struct val *vp;
int
is_integer(vp, r)
struct val *vp;
- int *r;
+ int64_t *r;
{
char *s;
int neg;
- int i;
+ int64_t i;
if (vp->type == integer) {
*r = vp->u.i;
i = 0;
neg = (*s == '-');
- if (neg)
+ if (neg) {
s++;
+ /* the optional unary minus *must* be followed by digits to
+ * be considered an integer. A '-' alone is not an integer.
+ */
+ if(!*s)
+ return 0;
+ }
while (*s) {
if (!isdigit(*s))
to_integer(vp)
struct val *vp;
{
- int r;
+ int64_t r;
if (vp->type == integer)
return 1;
if (vp->type == string)
return;
- tmp = malloc(25);
+ tmp = malloc(100);
if (tmp == NULL) {
err(2, "%s", "");
}
- (void)snprintf(tmp, 25, "%d", vp->u.i);
+ (void)snprintf(tmp, 100, "%lld", vp->u.i);
vp->type = string;
vp->u.s = tmp;
}
+int is_null(vp)
+ struct val *vp;
+{
+ if ((vp->type != integer) && (*vp->u.s == 0))
+ return 1;
+ return 0;
+}
+
int
is_zero_or_null(vp)
struct val *vp;
struct val *l, *r;
enum token op;
int v = 0; /* pacify gcc */
- int li, ri;
+ int64_t li, ri;
l = eval3();
while ((op = token) == EQ || op == NE || op == LT || op == GT || op == LE || op == GE) {
if (is_zero_or_null(l)) {
free_value(l);
l = r;
+ if( is_null(r) ) {
+ free_value(r);
+ l = make_int(0);
+ }
} else {
free_value(r);
}
(void) setlocale(LC_ALL, "");
av = argv + 1;
-
+ if (!strcmp(*av, "--"))
+ av++;
nexttoken();
vp = eval0();
if (token != EOI)
error();
-
+ if (vp->type == string && vp->u.s[0])
+ to_integer(vp); /* -0 is not a string */
if (vp->type == integer)
- (void)printf("%d\n", vp->u.i);
+ (void)printf("%lld\n", vp->u.i);
else
(void)printf("%s\n", vp->u.s);