Mercurial > hg > toybox
comparison lib/args.c @ 294:3de1ea4d6b56
Fix command line option parsing so "echo -xen" actually prints "-xen". Add
echo.test while I'm at it.
author | Rob Landley <rob@landley.net> |
---|---|
date | Sat, 17 May 2008 17:13:26 -0500 |
parents | a1fdf34d9504 |
children | 1bb9f53a7101 |
comparison
equal
deleted
inserted
replaced
293:6baa13382880 | 294:3de1ea4d6b56 |
---|---|
86 uint32_t excludes; | 86 uint32_t excludes; |
87 }; | 87 }; |
88 | 88 |
89 // Parse one command line option. | 89 // Parse one command line option. |
90 | 90 |
91 static void gotflag(struct getoptflagstate *gof) | 91 static int gotflag(struct getoptflagstate *gof) |
92 { | 92 { |
93 int type; | 93 int type; |
94 struct opts *opt = gof->this; | 94 struct opts *opt = gof->this; |
95 | 95 |
96 // Did we recognize this option? | 96 // Did we recognize this option? |
97 if (!opt) { | 97 if (!opt) { |
98 if (gof->noerror) return; | 98 if (gof->noerror) return 1; |
99 error_exit("Unknown option %s", gof->arg); | 99 error_exit("Unknown option %s", gof->arg); |
100 } | 100 } |
101 toys.optflags |= opt->edx[0]; | 101 toys.optflags |= opt->edx[0]; |
102 toys.optflags &= ~opt->edx[1]; | 102 toys.optflags &= ~opt->edx[1]; |
103 gof->excludes = opt->edx[2]; | 103 gof->excludes = opt->edx[2]; |
133 | 133 |
134 gof->arg = ""; | 134 gof->arg = ""; |
135 } | 135 } |
136 | 136 |
137 gof->this = NULL; | 137 gof->this = NULL; |
138 return 0; | |
138 } | 139 } |
139 | 140 |
140 // Fill out toys.optflags and toys.optargs. | 141 // Fill out toys.optflags and toys.optargs. |
141 | 142 |
142 static char *plustildenot = "+~!"; | 143 static char *plustildenot = "+~!"; |
148 struct opts *opt; | 149 struct opts *opt; |
149 char *str; | 150 char *str; |
150 int len; | 151 int len; |
151 } *longopts = NULL; | 152 } *longopts = NULL; |
152 struct getoptflagstate gof; | 153 struct getoptflagstate gof; |
153 long *nextarg = (long *)&this; | 154 long *nextarg = (long *)&this, saveflags; |
154 char *options = toys.which->options; | 155 char *options = toys.which->options; |
155 char *letters[]={"s",""}; | 156 char *letters[]={"s",""}; |
156 | 157 |
157 if (CFG_HELP) toys.exithelp++; | 158 if (CFG_HELP) toys.exithelp++; |
158 // Allocate memory for optargs | 159 // Allocate memory for optargs |
300 gof.this = lo->opt; | 301 gof.this = lo->opt; |
301 break; | 302 break; |
302 } | 303 } |
303 } | 304 } |
304 | 305 |
306 // Should we handle this --longopt as a non-option argument? | |
307 if (!lo && gof.noerror) { | |
308 gof.arg-=2; | |
309 goto notflag; | |
310 } | |
311 | |
305 // Long option parsed, handle option. | 312 // Long option parsed, handle option. |
306 gotflag(&gof); | 313 gotflag(&gof); |
307 continue; | 314 continue; |
308 } | 315 } |
309 | 316 |
313 else goto notflag; | 320 else goto notflag; |
314 } | 321 } |
315 | 322 |
316 // At this point, we have the args part of -args. Loop through | 323 // At this point, we have the args part of -args. Loop through |
317 // each entry (could be -abc meaning -a -b -c) | 324 // each entry (could be -abc meaning -a -b -c) |
325 saveflags = toys.optflags; | |
318 while (*gof.arg) { | 326 while (*gof.arg) { |
319 | 327 |
320 // Identify next option char. | 328 // Identify next option char. |
321 for (gof.this = gof.opts; gof.this; gof.this = gof.this->next) | 329 for (gof.this = gof.opts; gof.this; gof.this = gof.this->next) |
322 if (*gof.arg == gof.this->c) break; | 330 if (*gof.arg == gof.this->c) break; |
323 | 331 |
324 // Handle option char (advancing past what was used) | 332 // Handle option char (advancing past what was used) |
325 gotflag(&gof); | 333 if (gotflag(&gof) ) { |
334 toys.optflags = saveflags; | |
335 gof.arg = toys.argv[gof.argc]; | |
336 goto notflag; | |
337 } | |
326 } | 338 } |
327 continue; | 339 continue; |
328 | 340 |
329 // Not a flag, save value in toys.optargs[] | 341 // Not a flag, save value in toys.optargs[] |
330 notflag: | 342 notflag: |