Add internal command-line argument parser API
This patch adds an internal command-line argument parser API.
The exact API is well documented in `src/argpar/argpar.h`.
The features that I'm looking for are:
* C API.
* Support for ordered arguments in the results, even between options and
non-option arguments (sometimes called positional arguments).
* Support for GNU-style arguments, including "glued" short options and
long options with `=` to set the option's argument.
* Portable.
* Compatible license.
* No global variables (we're trying to avoid that programming style
throughout the project).
* Easy to use.
None of the popular libraries I looked at, including popt of course, met
all those specifications.
The goal of this is:
1. To simplify the parsing of general options (before the command name)
in bt_config_cli_args_create(). It is currently hard-coded.
This is not possible with popt because it would fail with an unknown
option, and you would not know the position of the command name's
argument within the array.
This is possible with g_option_context_parse().
2. To make it possible, in the `convert` command, to assign parameters
and other position-specific options to a non-option argument, for
example:
babeltrace2 /path/to/trace --params=some=param \
mein-other-trace --name=travel
This is not possible with popt as it collects all the non-option
arguments as an array of leftover arguments.
This is also not possible with g_option_context_parse() for the same
reasons as with popt.
getopt_long() could satisfy both 1. and 2., but it's somewhat a pain to
use and to maintain the available options, as you need to specify the
long options in a table and the equivalent short options as a single
string with a special encoding (the `convert` command's option string
would be particularily ugly). Also: getopt_long() plays a lot with
global variables; it's not thread-safe: the parser's state is global.
Also: the upstream getopt_long()'s (glibc) license is LGPL, which is
more restrictive than our MIT license, so I think we want to avoid that.
I believe having our own (tested) CLI argument parser is beneficial,
especially in the long term: we can drop a direct dependency (and popt
is getting old), not introduce a new one, it's about 450 lines of
documented C code, and if we ever need something very specific in the
argument parsing strategy in the future, we can add it directly. As a
reference, FFmpeg, a project which has complex argument parsing, similar
to Babeltrace's `convert` and `run` commands, has its own argument
parser (see parse_options() in [1]).
Only the CLI will use the bt_argpar_*() API, but to make the unit tests
simpler, I put it in its own convenience library.
[1]: https://github.com/FFmpeg/FFmpeg/blob/
b7b6ddd59693008c35b3247496ecc946331d0856/fftools/cmdutils.c
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: Iff4fc305b9e9171c694e1e79428bd3838ddd989d
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1646
CI-Build: Simon Marchi <simon.marchi@efficios.com>
Tested-by: jenkins <jenkins@lttng.org>