]> git.saurik.com Git - apple/shell_cmds.git/blobdiff - expr/expr.c
shell_cmds-149.tar.gz
[apple/shell_cmds.git] / expr / expr.c
index 4732044b8bf2efd42b8430a56a523d590f0a7bee..590608c8941472f1d9b3b5b03c53393f6270fc1d 100644 (file)
@@ -41,6 +41,7 @@ void free_value __P((struct val *));
 int is_integer __P((struct val *, int64_t *));
 int to_integer __P((struct val *));
 void to_string __P((struct val *));
 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__));
 int is_zero_or_null __P((struct val *));
 void nexttoken __P((void));
 void error __P((void)) __attribute__((__noreturn__));
@@ -118,8 +119,14 @@ is_integer(vp, r)
        i = 0;
 
        neg = (*s == '-');
        i = 0;
 
        neg = (*s == '-');
-       if (neg)
+       if (neg) {
                s++;
                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))
 
        while (*s) {
                if (!isdigit(*s))
@@ -179,6 +186,14 @@ to_string(vp)
        vp->u.s = tmp;
 }
 
        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;
 int
 is_zero_or_null(vp)
        struct val     *vp;
@@ -239,7 +254,7 @@ error()
 struct val *
 eval6()
 {
 struct val *
 eval6()
 {
-       struct val     *v;
+       struct val *v;
 
        if (token == OPERAND) {
                nexttoken();
 
        if (token == OPERAND) {
                nexttoken();
@@ -250,11 +265,73 @@ eval6()
                v = eval0();
 
                if (token != LP)
                v = eval0();
 
                if (token != LP)
-                       error();
+                       error();
+                 
                nexttoken();
                return v;
        } else {
                nexttoken();
                return v;
        } else {
-               error();
+          
+               switch (token) {
+               case DIV:
+                        nexttoken();
+                        tokval = make_str("/");
+                        break;
+               case MUL: 
+                        nexttoken();
+                        tokval = make_str("*");
+                        break;
+               case OR: 
+                        nexttoken();
+                        tokval = make_str("|");
+                        break;
+               case AND: 
+                        nexttoken();
+                        tokval = make_str("&");
+                        break;
+               case EQ: 
+                        nexttoken();
+                        tokval = make_str("=");
+                        break;
+               case LT: 
+                        nexttoken();
+                        tokval = make_str("<");
+                        break;
+               case GT: 
+                        nexttoken();
+                        tokval = make_str(">");
+                        break;
+               case ADD: 
+                        nexttoken();
+                        tokval = make_str("+");
+                        break;
+               case SUB: 
+                        nexttoken();
+                        tokval = make_str("-");
+                        break;
+               case MOD: 
+                        nexttoken();
+                        tokval = make_str("%");
+                        break;
+               case NE: 
+                        nexttoken();
+                        tokval = make_str("!=");
+                        break;
+               case LE: 
+                        nexttoken();
+                        tokval = make_str("<=");
+                        break;
+               case MATCH:
+                        nexttoken();
+                        tokval = make_str(":");
+                        break;
+               case GE: 
+                        nexttoken();
+                        tokval = make_str(">=");
+                        break;
+               case EOI:
+                        error();
+               }
+               return tokval;
        }
        /* NOTREACHED */
 }
        }
        /* NOTREACHED */
 }
@@ -513,6 +590,10 @@ eval0()
                if (is_zero_or_null(l)) {
                        free_value(l);
                        l = r;
                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);
                }
                } else {
                        free_value(r);
                }
@@ -531,13 +612,15 @@ main(argc, argv)
 
        (void) setlocale(LC_ALL, "");
        av = argv + 1;
 
        (void) setlocale(LC_ALL, "");
        av = argv + 1;
-
+       if (*av && !strcmp(*av, "--"))
+           av++;
        nexttoken();
        vp = eval0();
 
        if (token != EOI)
                error();
        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("%lld\n", vp->u.i);
        else
        if (vp->type == integer)
                (void)printf("%lld\n", vp->u.i);
        else