Skip to content

Commit

Permalink
Expand toys.optargs to 64 bits so people adding more options to ls do…
Browse files Browse the repository at this point in the history
…n'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.
  • Loading branch information
landley committed Dec 10, 2015
1 parent 5cb6505 commit aaecbba
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 14 deletions.
10 changes: 5 additions & 5 deletions lib/args.c
Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down
22 changes: 14 additions & 8 deletions scripts/mkflags.c
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
Expand Down
2 changes: 1 addition & 1 deletion toys.h
Expand Up @@ -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
Expand Down
22 changes: 22 additions & 0 deletions 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);
}

0 comments on commit aaecbba

Please sign in to comment.