I want to use argp
in my C program to parse command line options.
One requirement is that an option does not have a short name (like -f bar
) but only a long name (like --foo=bar
).
My approach so far is to set the key
field of the argp_option
struct to 0
to make it not show a short name.
I have looked at the provided examples and argp.h
in detail but I can't find a means to parse an option that only has a long name in the parser function that is given to argp
.
What I did find out is that, theoretically, in the parser I could use
case ARGP_KEY_ARG:
printf("%s\n", arg);
to find the value of long options (e.g. when called with --foo=bar
, bar
would be printed here). However, this doesn't seem like the right approach since I don't see a simple way to actually tell which option the value belongs to. and this also shows actual command line arguments (not option values).
I'd be thankful for any tips about where I need to look. Cheers.
From "The GNU C Library: Argp Option Vectors — Specifying Options in an Argp Parser":
int key
The integer
key
provided by the current option to the option parser. Ifkey
has a value that is a printable ASCII character (i.e.,isascii (key)
is true), it also specifies a short option-char
, wherechar
is the ASCII character with the codekey
.
In other words, the key
field of an option can be any int
value, and if isascii(key)
is nonzero, then it also specifies a short option—meaning you can use non-ASCII values (values outside the range 0x00
..0x7F
) to avoid the short option. Despite not being a short option, the value of key
is still used as the value of the associated long option (e.g. --foo
), so you'd handle it the same as any key/short option.
O/T: I collect all of my option keys in an enum
as constants, so I'm not wondering what option 0x100
represents in a switch
, e.g. for GNU tar
, it might be something like this for its compression options:
enum compress_options {
// Archive file extension determines compression program
COMP_FILTER_AUTO = 'a',
// Option arg is program used to deal with compression
COMP_FILTER_ARG = 'I',
COMP_FILTER_BZIP2 = 'j',
COMP_FILTER_XZ = 'J',
COMP_FILTER_GZIP = 'z',
COMP_FILTER_COMPRESS = 'Z',
COMP_FILTER_LZIP = 0x100,
COMP_FILTER_LZMA,
COMP_FILTER_LZOP,
// Do not use archive suffix to determine compression program.
COMP_FILTER_NOAUTO,
};
Then you'd just need to ensure that the next set of options uses 0x200
, then 0x300
, etc. to avoid issues with options having the same value. If you needed, you could also use 0x100
, 0x180
, 0x200
, 0x280
, etc. (e.g. 0x100
might represent a subcommand and 0x180
might be the first option for that subcommand).
It's important to group the short options and non-short options separately. The implicitly assigned values in an enum
depend upon the value of the last explicitly assigned value. Had I placed COMP_FILTER_NOAUTO
immediately after COMP_FILTER_AUTO
, the --no-auto-compress
long option would have an associated short option -b
, which it does not in reality.