Hi,

Third change resubmit for review.

Recap:

+ Makes it able to output calculation results in hex and octal. This is of course the reverse functionality to the previous. Works like this:

    skynet:/usr/src/bin/expr# expr -x 16383
    3fff
    skynet:/usr/src/bin/expr# expr -o 16383
    37777
    skynet:/usr/src/bin/expr# expr -X 16383
    3FFF
    skynet:/usr/src/bin/expr# expr -cx 16383
    0x3fff
    skynet:/usr/src/bin/expr#

- Since expr previously ignored switches altogether, strings starting with '-' will no longer be recognized as strings, but probably generate a "usage:" error message instead. This can be circumvented by the -- notation, and that particular form was actually supported before as well. But still this might be a problem since there is a slim chance it can break current shell scripts. I can't think of a better / more backwards compatible way to implement different output radixes though.

- And of course POSIX, this everlasting spectre?

(This diff is done relative to the first two.)

----8<--------8<--------8<--------8<--------8<---- (cut)
--- expr.c.diff2        Sat Jan 15 04:46:46 2011
+++ expr.c      Sat Jan 15 04:50:45 2011
@@ -502,14 +502,39 @@
 int
 main(int argc, char *argv[])
 {
-       struct val     *vp;
+       struct val      *vp;
+       int             oradix=10;
+       int             cprefix=0;
+       int             c;
+       extern char     *__progname;

        (void) setlocale(LC_ALL, "");

-       if (argc > 1 && !strcmp(argv[1], "--"))
-               argv++;
+       while ((c=getopt(argc, argv, "coxX")) != -1) {
+               switch (c) {
+                       case 'c':
+                               cprefix=1;
+                               break;
+                       case 'o':
+                               oradix=8;
+                               break;
+                       case 'x':
+                               oradix=16;
+                               break;
+                       case 'X':
+                               oradix=-16;
+                               break;
+                       default:
+                               fprintf(stderr,
+                                       "usage: %s [-coxX] <expression>\n",
+                                       __progname);
+                               exit(2); /* Tell user invalid expression */
+               }
+       }
+       argc -= optind;
+       argv += optind;

-       av = argv + 1;
+       av = argv;

        nexttoken(0);

@@ -526,9 +551,21 @@
                /* NOTREACHED */
        }

-       if (vp->type == integer)
-               printf("%ld\n", vp->u.i);
-       else
+       if (vp->type == integer) {
+               switch (oradix) {
+                       case 8:
+                               printf("%s%lo\n", cprefix ? "0" : "", vp->u.i);
+                               break;
+                       case 16:
+                               printf("%s%lx\n", cprefix ? "0x" : "", vp->u.i);
+                               break;
+                       case -16:
+                               printf("%s%lX\n", cprefix ? "0X" : "", vp->u.i);
+                               break;
+                       default:
+                               printf("%ld\n", vp->u.i); break;
+               }
+       } else
                printf("%s\n", vp->u.s);

        exit(is_zero_or_null(vp));
----8<--------8<--------8<--------8<--------8<---- (cut)

--
internetlabbet.se     / work:   +46 8 551 124 80      / "Words must
Benny Lvfgren        /  mobile: +46 70 718 11 90     /   be weighed,
                    /   fax:    +46 8 551 124 89    /    not counted."
                   /    email:  benny -at- internetlabbet.se

Reply via email to