Parser for argv that works similarly to getopt; Jørgen Ibsen (2015).
npm install parg.c 
About
-----
Most command-line programs have to parse options, so there are a lot of
different solutions to this problem. Some offer many features, while others
are more basic.
One of the simpler solutions for C is the [getopt][] function, and its
extension getopt_long. They iterate over the options in argv, returning
them one at a time on successive calls.
One nice thing about them is that they are available on most Unix-like
operating systems (and usually accompany GCC elsewhere, like Windows).
Unfortunately, some implementation details vary between platforms.
A potential question is what license the version you get when you include
them is available under. Some are GPL, others LGPL. There are also ports of
getopt that use more liberal licenses.
parg is a parser for argv that works similarly to getopt, but does not
aim to be a direct replacement. It attempts to make some choices about how to
handle the extensions and idiosyncrasies of other getopt implementations,
and document them.
It consists of a single source and include file, written in portable ANSI C.
It is made available under the MIT No Attribution License (MIT-0).
It is written by Jørgen Ibsen.
[getopt]: https://en.wikipedia.org/wiki/Getopt
Installation
------------
Run:
``sh
`
$ npm i parg.c
parg.h
And then include as follows:
`
c
`
// main.c
#define PARG_IMPLEMENTATION
#include
int main() { / ... / }
node_modules/parg.c
Finally, compile while adding the path to your compiler's include paths.
`
bash
`
$ clang -I./node_modules/parg.c main.c # or, use gcc
$ gcc -I./node_modules/parg.c main.c
`
You may also use a simpler approach with the cpoach tool, which automatically adds the necessary include paths of all the installed dependencies for your project.
bash
`
$ cpoach clang main.c # or, use gcc
$ cpoach gcc main.c
parg.h
Usage
-----
The include file contains documentation in the form of [doxygen][]
doxygen
comments. A configuration file is included, run to generate
parg.c
documentation in HTML format.
You can include and parg.h in your own projects.
parg
For CI, uses [CMake][] to provide an easy way to build and test across
parg
various platforms and toolsets. To create a build system for the tools on your
platform, and build , use something along the lines of:
parg_getopt()
~~~sh
mkdir build
cd build
cmake ..
cmake --build .
~~~
[doxygen]: http://www.doxygen.org/
[CMake]: http://www.cmake.org/
Example
-------
Here is an example that parses command-line options using :
getopt
~~~c
#include
#include
#define PARG_IMPLEMENTATION
#include
int main(int argc, char *argv[])
{
struct parg_state ps;
int c;
parg_init(&ps);
while ((c = parg_getopt(&ps, argc, argv, "hs:v")) != -1) {
switch (c) {
case 1:
printf("nonoption '%s'\n", ps.optarg);
break;
case 'h':
printf("Usage: testparg [-h] [-v] [-s STRING]\n");
return EXIT_SUCCESS;
break;
case 's':
printf("option -s with argument '%s'\n", ps.optarg);
break;
case 'v':
printf("testparg 1.0.0\n");
return EXIT_SUCCESS;
break;
case '?':
if (ps.optopt == 's') {
printf("option -s requires an argument\n");
}
else {
printf("unknown option -%c\n", ps.optopt);
}
return EXIT_FAILURE;
break;
default:
printf("error: unhandled option -%c\n", c);
return EXIT_FAILURE;
break;
}
}
for (c = ps.optind; c < argc; ++c) {
printf("nonoption '%s'\n", argv[c]);
}
return EXIT_SUCCESS;
}
~~~
Comparison to
getopt
----------------------
$3
uses global variables to store its state between calls. parg uses
parg_state
a struct , which you must pass with each call.
getopt
$3
POSIX and BSD return -1 on the first nonoption argument. GNU
getopt by default reorders argv (even though it is passed as const), so
parg
all options come first.
does not change argv, and returns each nonoption as the option
1
argument of an option with value (like GNU getopt, if optstring were
-
prefixed by '').
argv
If you wish to process all options first, and have the nonoptions ordered at
the end of , you can use parg_reorder():
getopt
~~~c
optend = parg_reorder(argc, argv, optstring, NULL);
while ((c = parg_getopt(&ps, optend, argv, optstring)) != -1) {
/ ... /
}
/ elements of argv[] from optend to argc are nonoptions /
~~~
$3
When there are multiple short options in one argument, does not
optind
increment until the last one is processed. This makes it harder to
a
tell which argument an unknown option came from (if is an unknown option,
-a and -ab will return '?' with different values in optind).
parg
always increments the optind value in it's state so it points to the
argv
next element to be processed. So when parg returns '?' (or ':'),
argv[optind - 1]
the element that contains the error is .
getopt_long
$3
With , it varies what the values of optopt and longindex are
parg
when an error is found with option arguments of long options. Sometimes these
values are not documented.
sets optopt to val if flag is NULL, and 0 otherwise (which
longindex
equals the return value on successful match), and is set to the
longopts
index of the entry in that matched.
optstring
$3
When the first character of is ':', it varies what getopt
parg
returns on extraneous option arguments.
In this case, returns '?' if no option match is found, and ':' if
getopt`:
a match is found, but is missing a required argument, or has an extraneous
argument.
Alternatives
------------
Some ports of
- Free Getopt
- ya_getopt
- getopt_port
Other command-line parsing libraries that support C:
- Gengetopt
- Argp
- popt
- argtable
- optlist
- Arg_parser
- Gopt
- docopt
- optparse
- getopt
- argparse
A few C++ command-line parsing libraries:
- TCLAP
- program_options
- CommandLine
- CLI11
- argparse
- clipp
- argh



