aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Landley <rob@landley.net>2020-11-14 23:39:18 -0600
committerRob Landley <rob@landley.net>2020-11-14 23:39:18 -0600
commit52bbc1e0a410b44a926b04aaae3b00f9f50da81e (patch)
treea909959953794b6faafc2731b1bcccfbb5faf941
parent3e28f611e452b52b21360c56dbf250d242bbb4a5 (diff)
downloadtoybox-52bbc1e0a410b44a926b04aaae3b00f9f50da81e.tar.gz
Allow 0 prefix to optstr to include argv[0] in optargs[0].
-rw-r--r--lib/args.c15
-rw-r--r--scripts/mkflags.c19
-rw-r--r--toys/posix/env.c2
3 files changed, 21 insertions, 15 deletions
diff --git a/lib/args.c b/lib/args.c
index 83bceaf0..ac83a0fe 100644
--- a/lib/args.c
+++ b/lib/args.c
@@ -76,6 +76,7 @@
// >9 die if > # leftover arguments (default MAX_INT)
// ? Allow unknown arguments (pass them through to command).
// & first arg has imaginary dash (ala tar/ps/ar) which sets FLAGS_NODASH
+// 0 Include argv[0] in optargs
//
// At the end: [groups] of previously seen options
// - Only one in group (switch off) [-abc] means -ab=-b, -ba=-a, -abc=-c
@@ -226,17 +227,17 @@ static int gotflag(struct getoptflagstate *gof, struct opts *opt)
// Parse this command's options string into struct getoptflagstate, which
// includes a struct opts linked list in reverse order (I.E. right-to-left)
-void parse_optflaglist(struct getoptflagstate *gof)
+int parse_optflaglist(struct getoptflagstate *gof)
{
char *options = toys.which->options;
long *nextarg = (long *)&this;
struct opts *new = 0;
- int idx;
+ int idx, rc = 0;
// Parse option format string
memset(gof, 0, sizeof(struct getoptflagstate));
gof->maxargs = INT_MAX;
- if (!options) return;
+ if (!options) return 0;
// Parse leading special behavior indicators
for (;;) {
@@ -245,6 +246,7 @@ void parse_optflaglist(struct getoptflagstate *gof)
else if (*options == '>') gof->maxargs=*(++options)-'0';
else if (*options == '?') gof->noerror++;
else if (*options == '&') gof->nodash_now = 1;
+ else if (*options == '0') rc = 1;
else break;
options++;
}
@@ -371,6 +373,8 @@ void parse_optflaglist(struct getoptflagstate *gof)
}
}
}
+
+ return rc;
}
// Fill out toys.optflags, toys.optargs, and this[] from toys.argv
@@ -388,11 +392,10 @@ void get_optflags(void)
toys.exitval = toys.which->flags >> 24;
// Allocate memory for optargs
- saveflags = 0;
+ saveflags = toys.optc = parse_optflaglist(&gof);
while (toys.argv[saveflags++]);
toys.optargs = xzalloc(sizeof(char *)*saveflags);
-
- parse_optflaglist(&gof);
+ if (toys.optc) *toys.optargs = *toys.argv;
if (toys.argv[1] && toys.argv[1][0] == '-') gof.nodash_now = 0;
diff --git a/scripts/mkflags.c b/scripts/mkflags.c
index fff9dd4c..7ea8770d 100644
--- a/scripts/mkflags.c
+++ b/scripts/mkflags.c
@@ -22,21 +22,23 @@ struct flag {
int chrtype(char c)
{
// Does this populate a GLOBALS() variable?
- if (strchr("?&^-:#|@*; %", c)) return 1;
+ if (strchr("^-:#|@*; %.", c)) return 1;
// Is this followed by a numeric argument in optstr?
if (strchr("=<>", c)) return 2;
+ if (strchr("?&0", c)) return 3;
+
return 0;
}
// replace chopped out USE_BLAH() sections with low-ascii characters
-// showing how many flags got skipped
+// showing how many flags got skipped so FLAG_ macros stay constant
char *mark_gaps(char *flags, char *all)
{
char *n, *new, c;
- int bare = 1;
+ int bare = 2;
// Shell feeds in " " for blank args, leading space not meaningful.
while (isspace(*flags)) flags++;
@@ -48,7 +50,8 @@ char *mark_gaps(char *flags, char *all)
if (*all == '(') {
int len = 0;
- while (all[len++] != ')');
+ if (bare) bare = 1;
+ while (all[len]) if (all[len++] == ')') break;
if (strncmp(flags, all, len)) {
// bare longopts need their own skip placeholders
if (bare) *(new++) = 1;
@@ -61,7 +64,7 @@ char *mark_gaps(char *flags, char *all)
continue;
}
c = *(all++);
- if (bare) bare = chrtype(c);
+ if (bare && !chrtype(c)) bare = 0;
if (*flags == c) {
*(new++) = c;
flags++;
@@ -69,7 +72,7 @@ char *mark_gaps(char *flags, char *all)
}
c = chrtype(c);
- if (!c) *(new++) = 1;
+ if (!c || (!bare && c==3)) *(new++) = 1;
else if (c==2) while (isdigit(*all)) all++;
}
*new = 0;
@@ -81,7 +84,7 @@ char *mark_gaps(char *flags, char *all)
struct flag *digest(char *string)
{
- struct flag *list = NULL;
+ struct flag *list = 0;
char *err = string, c;
while (*string) {
@@ -112,7 +115,7 @@ struct flag *digest(char *string)
}
c = chrtype(*string);
- if (c == 1) string++;
+ if (c == 1 || (c == 3 && !list)) string++;
else if (c == 2) {
if (string[1]=='-') string++;
if (!isdigit(string[1])) {
diff --git a/toys/posix/env.c b/toys/posix/env.c
index 7b944f07..750ba49a 100644
--- a/toys/posix/env.c
+++ b/toys/posix/env.c
@@ -6,7 +6,7 @@
*
* Deviations from posix: "-" argument and -0
-USE_ENV(NEWTOY(env, "^0iu*", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_ARGFAIL(125)))
+USE_ENV(NEWTOY(env, "^i0u*", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_ARGFAIL(125)))
config ENV
bool "env"