diff options
author | Rob Landley <rob@landley.net> | 2015-12-10 15:57:08 -0600 |
---|---|---|
committer | Rob Landley <rob@landley.net> | 2015-12-10 15:57:08 -0600 |
commit | aaecbbac2f94b7a93eb2df7f9db78828cbb7b647 (patch) | |
tree | ac2a23d038113e359b583e042170d9d319690cf2 | |
parent | 5cb65054067391af7602bc303d77349c76648faf (diff) | |
download | toybox-aaecbbac2f94b7a93eb2df7f9db78828cbb7b647.tar.gz |
Expand toys.optargs to 64 bits so people adding more options to ls don't run out.
Keep the low 32 bits of FLAG_x constants as 32 bit numbers so that at least
on little endian platforms it's still normal 32 bit math outside of lib/args.c.
-rw-r--r-- | lib/args.c | 10 | ||||
-rw-r--r-- | scripts/mkflags.c | 22 | ||||
-rw-r--r-- | toys.h | 2 | ||||
-rw-r--r-- | toys/example/test_many_options.c | 22 |
4 files changed, 42 insertions, 14 deletions
@@ -97,8 +97,8 @@ struct opts { struct opts *next; long *arg; // Pointer into union "this" to store arguments at. int c; // Argument character to match - int flags; // |=1, ^=2 - unsigned dex[3]; // which bits to disable/enable/exclude in toys.optflags + int flags; // |=1, ^=2, " "=4, ;=8 + unsigned long long dex[3]; // bits to disable/enable/exclude in toys.optflags char type; // Type of arguments to store union "this" union { long l; @@ -142,7 +142,7 @@ static int gotflag(struct getoptflagstate *gof, struct opts *opt) // Might enabling this switch off something else? if (toys.optflags & opt->dex[0]) { struct opts *clr; - unsigned i = 1; + unsigned long long i = 1; // Forget saved argument for flag we switch back off for (clr=gof->opts, i=1; clr; clr = clr->next, i<<=1) @@ -326,7 +326,7 @@ void parse_optflaglist(struct getoptflagstate *gof) // (This goes right to left so we need the whole list before we can start.) idx = 0; for (new = gof->opts; new; new = new->next) { - unsigned u = 1<<idx++; + unsigned long long u = 1L<<idx++; if (new->c == 1) new->c = 0; new->dex[1] = u; @@ -378,7 +378,7 @@ void get_optflags(void) { struct getoptflagstate gof; struct opts *catch; - long saveflags; + unsigned long long saveflags; char *letters[]={"s",""}; // Option parsing is a two stage process: parse the option string into diff --git a/scripts/mkflags.c b/scripts/mkflags.c index b57f0577..e7ed684a 100644 --- a/scripts/mkflags.c +++ b/scripts/mkflags.c @@ -116,8 +116,8 @@ int main(int argc, char *argv[]) // See "intentionally crappy", above. if (!(out = outbuf)) return 1; - printf("#ifdef FORCE_FLAGS\n#define FORCED_FLAG 1\n" - "#else\n#define FORCED_FLAG 0\n#endif\n\n"); + printf("#ifdef FORCE_FLAGS\n#define FORCED_FLAG 1\n#define FORCED_FLAGLL 1LL\n" + "#else\n#define FORCED_FLAG 0\n#define FORCED_FLAGLL 0\n#endif\n\n"); for (;;) { struct flag *flist, *aflist, *offlist; @@ -173,27 +173,33 @@ int main(int argc, char *argv[]) out += strlen(out); while (aflist) { + char *llstr = bit>31 ? "LL" : ""; + + // Output flag macro for bare longopts if (aflist->lopt) { if (flist && flist->lopt && !strcmp(flist->lopt->command, aflist->lopt->command)) { - sprintf(out, "#define FLAG_%s (1<<%d)\n", flist->lopt->command, bit); + sprintf(out, "#define FLAG_%s (1%s<<%d)\n", flist->lopt->command, + llstr, bit); flist->lopt = flist->lopt->next; - } else sprintf(out, "#define FLAG_%s (FORCED_FLAG<<%d)\n", - aflist->lopt->command, bit); + } else sprintf(out, "#define FLAG_%s (FORCED_FLAG%s<<%d)\n", + aflist->lopt->command, llstr, bit); aflist->lopt = aflist->lopt->next; if (!aflist->command) { aflist = aflist->next; bit++; if (flist) flist = flist->next; } + // Output normal flag macro } else if (aflist->command) { if (flist && (!flist->command || *aflist->command == *flist->command)) { if (aflist->command) - sprintf(out, "#define FLAG_%c (1<<%d)\n", *aflist->command, bit); + sprintf(out, "#define FLAG_%c (1%s<<%d)\n", *aflist->command, + llstr, bit); flist = flist->next; - } else sprintf(out, "#define FLAG_%c (FORCED_FLAG<<%d)\n", - *aflist->command, bit); + } else sprintf(out, "#define FLAG_%c (FORCED_FLAG%s<<%d)\n", + *aflist->command, llstr, bit); bit++; aflist = aflist->next; } @@ -122,7 +122,7 @@ extern struct toy_context { struct toy_list *which; // Which entry in toy_list is this one? char **argv; // Original command line arguments char **optargs; // Arguments left over from get_optflags() - unsigned optflags; // Command line option flags from get_optflags() + unsigned long long optflags; // Command line option flags from get_optflags() int exitval; // Value error_exit feeds to exit() int optc; // Count of optargs int old_umask; // Old umask preserved by TOYFLAG_UMASK diff --git a/toys/example/test_many_options.c b/toys/example/test_many_options.c new file mode 100644 index 00000000..d2f5c846 --- /dev/null +++ b/toys/example/test_many_options.c @@ -0,0 +1,22 @@ +/* test_many_options.c - test more than 32 bits worth of option flags + * + * Copyright 2015 Rob Landley <rob@landley.net> + +USE_TEST_MANY_OPTIONS(NEWTOY(test_many_options, "ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba", TOYFLAG_USR|TOYFLAG_BIN)) + +config TEST_MANY_OPTIONS + bool "test_many_options" + default n + help + usage: test_many_options -[a-zA-Z] + + Print the optflags value of the command arguments, in hex. +*/ + +#define FOR_test_many_options +#include "toys.h" + +void test_many_options_main(void) +{ + xprintf("optflags=%llx\n", toys.optflags); +} |