]> git.saurik.com Git - apple/shell_cmds.git/blobdiff - expr/expr.c
shell_cmds-81.tar.gz
[apple/shell_cmds.git] / expr / expr.c
index 53234270503fdf52c3f66ffc535c466dc623d12d..36b998f6f4146091c170a05ffc7e3fccaab7ccb0 100644 (file)
@@ -27,7 +27,7 @@ struct val {
 
        union {
                char           *s;
-               int             i;
+               int64_t             i;
        } u;
 };
 
@@ -35,12 +35,13 @@ enum token  token;
 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__));
@@ -56,7 +57,7 @@ int main __P((int, char **));
 
 struct val *
 make_int(i)
-       int             i;
+       int64_t             i;
 {
        struct val     *vp;
 
@@ -99,11 +100,11 @@ free_value(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;
@@ -118,8 +119,14 @@ is_integer(vp, r)
        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))
@@ -144,7 +151,7 @@ int
 to_integer(vp)
        struct val     *vp;
 {
-       int             r;
+       int64_t             r;
 
        if (vp->type == integer)
                return 1;
@@ -170,15 +177,23 @@ to_string(vp)
        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;
@@ -384,7 +399,7 @@ eval2()
        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) {
@@ -513,6 +528,10 @@ eval0()
                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);
                }
@@ -531,15 +550,17 @@ main(argc, argv)
 
        (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);