naki,
I know that plan 9 has its own approach to parse argumets, but I've never really read those macros before
Now, when I've read them, I thought that having ARGEND is not really that good, and in fact this feels kind of redundant to me
So, I've made my own implementation. It consists of 2 macros:
ARGS,
which is an engine to traverse argv
until the end or the double dash (--)
ARG(ifnot),
that fetches the next argument,
and if noargument found then ifnot gets executed.
I like to put errx() call there
Also,
there's a variable param
storing currently processed parameter
and _arg being temporary storage for the
ARG() macro
The code below is licensed under the public domain license, or isc license, as you wish:
/* these macros corrupt argc, argv, pointers * stored at argv belonging to options */ char param, *_arg; #define switchargs(argc, argv) for(++argv, --argc;\ argv[0] && argv[0][0]=='-' && argv[0][1]\ && !(argv[0][1]=='-' && argv[0][2]=='\0' && argv++ && argc--);\ ++argv, --argc)\ for(++argv[0]; argv[0][0];)\ switch(param=argv[0]++[0]) #define getarg(argc, argv, ifnot) (argv[0][0]? 0:\ argv[1]? ++argv, --argc:\ (ifnot), _arg=argv[0], argv[0]="", _arg)
Also, that's the way how it's intended to be used:
int
main(int argc, char **argv)
{
char *lopt;
switchargs(argc, argv){
break; case 'a': printf("flag a was triggered\n");
break; case 'b': printf("b: %s\n", getarg(argc, argv, errx(1, "no argument for b")));
break; case '-':
lopt = getarg(argc, argv, 0);
if (!strcmp(lopt, "long"))
printf("long: %s\n", getarg(argc, argv, errx(1, "no argument for long")));
else
printf("some unknown long option was passed (%s)\n", lopt);
break; default: printf("something other was passed (%c)\n", param);
}
puts("args left:");
for (; *argv; ++argv)
puts(*argv);
}