From 831266c06862c1be6195382a02b86cb52ef304dc Mon Sep 17 00:00:00 2001 From: Rob Landley Date: Wed, 26 Dec 2018 12:07:14 -0600 Subject: [PATCH] Teach the argument plumbing how to do -@ for mkfs.vfat --- lib/args.c | 7 +++++-- scripts/mkflags.c | 32 ++++++++++++++++++++++++++------ 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/lib/args.c b/lib/args.c index b24dd4170..54106c25a 100644 --- a/lib/args.c +++ b/lib/args.c @@ -84,6 +84,9 @@ // + Synonyms (switch on all) [+abc] means -ab=-abc, -c=-abc // ! More than one in group is error [!abc] means -ab calls error_exit() // primarily useful if you can switch things back off again. +// +// You may use octal escapes with the high bit (127) set to use a control +// character as an option flag. For example, \300 would be the option -@ // Notes from getopt man page // - and -- cannot be arguments. @@ -128,7 +131,7 @@ struct getoptflagstate unsigned excludes, requires; }; -// Use getoptflagstate to parse parse one command line option from argv +// Use getoptflagstate to parse one command line option from argv static int gotflag(struct getoptflagstate *gof, struct opts *opt) { int type; @@ -317,7 +320,7 @@ void parse_optflaglist(struct getoptflagstate *gof) continue; // Claim this option, loop to see what's after it. - } else new->c = *options; + } else new->c = 127&*options; options++; } diff --git a/scripts/mkflags.c b/scripts/mkflags.c index de02a121d..b28ae1e14 100644 --- a/scripts/mkflags.c +++ b/scripts/mkflags.c @@ -137,6 +137,21 @@ struct flag *digest(char *string) return list; } +// Parse C-style octal escape +void octane(char *from) +{ + unsigned char *to = (void *)from; + + while (*from) { + if (*from == '\\') { + *to = 0; + while (isdigit(*++from)) *to = (8**to)+*from-'0'; + to++; + } else *to++ = *from++; + } + *to = 0; +} + int main(int argc, char *argv[]) { char command[256], flags[1023], allflags[1024]; @@ -158,6 +173,8 @@ int main(int argc, char *argv[]) *command = *flags = *allflags = 0; bit = fscanf(stdin, "%255s \"%1023[^\"]\" \"%1023[^\"]\"\n", command, flags, allflags); + octane(flags); + octane(allflags); if (getenv("DEBUG")) fprintf(stderr, "command=%s, flags=%s, allflags=%s\n", @@ -186,12 +203,14 @@ int main(int argc, char *argv[]) command, command, command); while (offlist) { - struct flag *f = offlist->lopt; - while (f) { - printf("#undef FLAG_%s\n", f->command); - f = f->next; + char *s = (char []){0, 0, 0, 0}; + + if (!offlist->command) s = offlist->lopt->command; + else { + *s = *offlist->command; + if (127 < (unsigned char)*s) sprintf(s, "X%02X", 127&*s); } - if (offlist->command) printf("#undef FLAG_%c\n", *offlist->command); + printf("#undef FLAG_%s\n", s); offlist = offlist->next; } printf("#endif\n\n"); @@ -201,7 +220,7 @@ int main(int argc, char *argv[]) out += strlen(out); while (aflist) { - char *llstr = bit>31 ? "LL" : "", *s = (char []){0, 0}; + char *llstr = bit>31 ? "LL" : "", *s = (char []){0, 0, 0, 0}; int enabled = 0; // Output flag macro for bare longopts @@ -212,6 +231,7 @@ int main(int argc, char *argv[]) // Output normal flag macro } else { *s = *aflist->command; + if (127 < (unsigned char)*s) sprintf(s, "X%02X", 127&*s); if (flist && flist->command && *aflist->command == *flist->command) enabled++; }