'How to verify that an option argument is not another option in C getopt?
Take the following code for example:
while(-1 != (opt = getopt(argc, argv, "a:b:X")))
{
switch(opt)
{
case 'a':
printf("a arg: %s\n", optarg);
break;
case 'b':
printf("b arg: %s\n", optarg);
break;
case 'X':
printf("X provided\n");
break;
}
}
The following command-line command is acceptable by this:
$ ./a.out -a -X
getopt will not produce any error for this, although it is not desirable that the argument fo a is another option. Is there an elegant way to handle this in getopt?
Solution 1:[1]
The usual convention for argument parsing is that option arguments are not optional, and therefore an option argument can start with a dash. Indeed, sometimes utilities accept options with precisely the same semantics as a positional argument precisely to give the user a way to specify an argument which happens to start with a dash. (See grep -e, for example.)
If you choose to ignore this guideline, that's your privilege; utility argument guidelines are just guidelines, not laws; probably your utility is not covered by Posix anyway, and even if it were no-one's going to come after you with a writ. But you should note in the documentation that your utility does not conform to the usual guidelines, because many users will naturally assume that 8t does.
Having said all that, if you want to verify that an option argument doesn't start with a -, it's no more complicated than:
if (optarg && optarg[0] == '-') {
fputs("This utility doesn't permit option arguments to start with a '-'\n", stderr);
// Call usage() if you have such a thing.
exit(1);
}
Of course, you should only do that check in the action for an option which takes an argument, since the value of optarg is unspecified for other options. Testing that optarg is not NULL is only necessary if you are using Gnu getopt which allows you to indicate that an option's argument is optional (contrary to the usual guidelines) by following the option letter with two colons in the option string. (Presumably in that case the NULL is an expected possibility, and you shouldn't be doing the test anyway.)
Note that many utilities allow you to write an option argument immediately following the option (e g. tail -n-7); getopt does not provide any interface which lets you distinguish between that and tail -n -7, so you might end up rejecting invocations which are expected to be valid. Posix actually discourages this compact format, but it's so commonly allowed that it can be surprising when you encounter a utility like Gnu diff which doesn't allow it.
In short, there is a lot to be said for following usual practice. But it's your call.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
