For many uses, the traditional getopt function is enough to parse the options in command lines.
However, cases exist where getopt shows its limits. ctxopt is able to manage complex configurations of command line options and excels when they appear in structured or independent blocs.
In ctxopt, each option has the possibility of starting a new context in which the following command line options will be taken into account and analyzed. With this concept, it becomes easy, for example, to have repetitions of identical options with each their independent sub-options.
ctxopt has many features, its main ones are:
- Options are organized in a hierarchy of contexts.
- Options are easily declared using a syntax similar to BNF notation in each context.
- Any number of parameters can be assigned to each option.
- Parameters are not limited to just one character.
- The parameters associated with an option can be abbreviated as long as they do not conflict with another option in the same context.
- Parameters can be aggregated, even the long ones.
- Options evaluations trigger user-defined functions.
- Options can appear multiple times in one or more contexts.
- Options can be optional or mandatory.
- Option arguments can be optional or mandatory.
- Arguments can be multiple and their number controlled by simple rules.
- Arguments can have user-defined or built-in constraints.
- Options marked as mutually incompatibles are automatically detected.
- Command line options are normally evaluated in order but can be forced to be evaluated at the start of a context. They can also be asked to be reordered automatically to be evaluated before or after a set of other options in a context.
- Error functions can be customized.
- Automatic detection of missing|incompatible|unknown|... options or parameters.
Imagine a situation where you want an option to be allowed only if another option was previously given.
For example, you want the group option to be allowed only after a user option.
With ctxopt its easy, you just have to define two contexts (at least one
is mandatory), tell the user option to switch to the second context
(named ctx1
here) and define the group option in the second context.
Defined contexts | Allowed options | Next context | Option parameters |
---|---|---|---|
main |
user | ctx1 |
-u -user |
ctx1 |
group | -g -group |
According to the situation summarized in this table, the following command line (the context changes in brackets have been added only for understanding and not part of the command line)
prog[main] -u[ctx1] u1 -g g1 g2 -user[ctx1] u2 -group g3
will be understood as:
Context main: prog -u u1 -user u2 Context ctx1: -g g1 g2 -group g3
In this example, you can see that the previous context (main
here) is
automatically re-entered after the analysis of the group option because
the user option is unknown in the ctx1
context.
See the file example1.c in the examples directory for details.
To use ctxopt, the users must at least:
- include ctxopt.h and ctxopt.c in his code.
- define at least one context and describe its options.
- set at least one parameter's name for the options described in the contexts.
- write and attach an action callback function to each options.
- possibly register constraint and other things (optional).
- call
ctxopt_init
. - call
ctxopt_analyze
. - call
ctxopt_evaluate
.
Optional steps include:
- register entering and/or exiting function for contexts.
- register arguments constraint checking functions.
- redefine non internal error functions.
For more, please read the provided man page.
1 #include "ctxopt.h"
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5
6 /* Callback functions */
7 /* ****************** */
8
9 void name_action(char * ctx_name, char * opt_name, char * param,
10 int nb_values, char ** values, int nb_opt_data,
11 void ** opt_data, int nb_ctx_data, void** ctx_data)
12 {
13 int v;
14
15 printf("Hello %s", values[0]); /* First command line argument after name *
16 | (-n or -name). */
17
18 for (v = 1; v < nb_values; v++) /* Other command line arguments. */
19 printf(", %s", values[v]);
20
21 printf(".\n");
22 }
23
24 /* Program entry */
25 /* ************* */
26
27 int main(int argc, char * argv[])
28 {
29 int nb_rem_args = 0; /* Nb of remaining unprocessed arguments. */
30 char ** rem_args = NULL; /* Remaining arguments string array. */
31
32 ctxopt_init(argv[0], "stop_if_non_option=Yes allow_abbreviations=Yes");
33 ctxopt_new_ctx("main", "[name... #<string>...]");
34 ctxopt_add_opt_settings(parameters, "name", "-n -name");
35 ctxopt_add_opt_settings(actions, "name", name_action, NULL);
36 ctxopt_analyze(argc - 1, argv + 1, &nb_rem_args, &rem_args);
37
38 if (nb_rem_args > 0)
39 {
40 printf("Non-arguments are not allowed.\n");
41 exit(EXIT_FAILURE);
42 }
43
44 ctxopt_evaluate();
45
46 if (argc == 1)
47 printf("Hello world.\n");
48
49 exit(EXIT_SUCCESS);
50 }
Line 1:
This #include
gives access to the API necessary to use ctxopt.
Line 9:
This function is the callback function call each time a parameter associated with the option name is seen in the command line.
Line 32:
The init function is mandatory and must be called first.
Line 33:
Here the first (and unique here) context called main here is created with the description of an option called name.
The name option is defined as an optional possible multiple option taking mandatory possibly multiple arguments. It is the
#
which indicates the presence of an argument,<string>
is just a decaration to clarify the meaning of this argument.
Line 34:
It's now time to introduce the two parameters of the option name. These are the parameters looked for in the command line.
Line 35:
Here the callback function defined line 9 is associated with the option name.
Line 36:
Here the command line is parsed and errors like unknown parameter, not enough arguments... are detected. All errors detected during this phase are fatal.
Line 38:
The remaining non-arguments, if any, are managed here.
Line 44:
All the internal representation of the command line built during the analysis phase (line 36) is finally evaluated and the callback registered functions (here name_action) called.
Line 46:
The special case where the command line only contains the program name is treated here.
$ ./hello -n Alice Bob -name Carol Hello Alice, Bob. Hello Carol. $ ./hello -n -n requires argument(s). Synopsis: hello [-n|-name... #<string>...] Syntactic explanations: Only the parameters (prefixed by -) and the arguments, if any, must be entered. The following is just there to explain the other symbols displayed. #tag : argument tag giving a clue to its meaning. [...] : the object between square brackets is optional. ... : the previous object can be repeated more than one time. $ ./hello Hello world.