aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Landley <rob@landley.net>2015-12-10 15:57:08 -0600
committerRob Landley <rob@landley.net>2015-12-10 15:57:08 -0600
commitaaecbbac2f94b7a93eb2df7f9db78828cbb7b647 (patch)
treeac2a23d038113e359b583e042170d9d319690cf2
parent5cb65054067391af7602bc303d77349c76648faf (diff)
downloadtoybox-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.c10
-rw-r--r--scripts/mkflags.c22
-rw-r--r--toys.h2
-rw-r--r--toys/example/test_many_options.c22
4 files changed, 42 insertions, 14 deletions
diff --git a/lib/args.c b/lib/args.c
index 594a1b47..1f42cdde 100644
--- a/lib/args.c
+++ b/lib/args.c
@@ -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;
}
diff --git a/toys.h b/toys.h
index 9c33ff21..688d5585 100644
--- a/toys.h
+++ b/toys.h
@@ -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);
+}