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