lopsub-suite(5) | File Formats Manual | lopsub-suite(5) |
lopsub-suite - lopsub suite syntax
A lopsub suite describes the options to a command line utility with zero or more related subcommands. The lopsubgen(1) utility translates a lopsub suite into either C source code or a manual page. The generated C code can be compiled and linked against the lopsub library to produce command line parsers for the main command and all subcommands defined in the suite.
This document explains the format of a lopsub suite. The overall structure is as follows:
[suite mysuite] suite directives [supercommand sup_cmd] command directives for sup_cmd [option opt1] ... (further options) [subcommand sub1] command directives for sub1 [option opt_1_to_sub1] option directives for opt_1 ... (further options) ... (further subcommands) [section see also] ... (optional extra section for man page) ... (further extra sections)
A suite begins with a [suite] line which declares the name of the suite. The suite directives, all subsequent lines up to the first [supercommand] or [subcommand] line, state further properties of the suite which are unrelated to any particular command, for example the version number. All available suite directives are summarized below.
The [supercommand] and [subcommand] lines indicate the beginning of a command of the suite. The part between this line and the first [option] line contains the command directives, for example the purpose and the description of the named command. See the section on command directives below.
Supercommands and subcommands share the same set of possible command directives. They differ mainly in the way the documentation is formatted. There can only be one supercommand but arbitrary many subcommands. For example, the supercommand could be the name of the application, and the subcommands could be "load", "save" "info" and "quit". The subcommand would be passed as the first non-option argument to the supercommand, followed by options specific to that subcommand.
Of course it is possible to define no subcommands at all. Conversely, one can define only subcommands but no supercommand. This makes sense if the commands are run by some other means, for example in an interactive session from a command prompt.
Within the command section, an [option] line starts an option to the current command. It is followed by option directives, which specify, for example, whether or not the option takes an argument. All supported option directives are listed in the corresponding section below.
Further material for man output can be included between the [section] and [/section] markers. This text will not be included in the generated .c and .h files and is thus also not part of the short and long help available at run time. The text is not interpreted except that leading whitespace is stripped from each line. Arbitrary roff source can be included here.
Empty lines and lines starting with a hash character (#) are ignored.
Most directives of this section are only relevant for man page output (with aux_info_default being the exception), they are ignored for C output.
Closing remarks for the command can be added in a similar way by enclosing plain text between [closing] and [/closing]. This text will be positioned after the option list.
If this is not given, the command is assumed to take no arguments other than the specified options and their arguments. For such commands the attempt to parse an argv[] vector fails if it contains further non-option arguments.
The value, if specified, is also copied to the man page at the end of the section for the command.
This directive is ignored for flag options (options without an argument).
Note that arguments to options which take an optional argument must be given as --foo=bar rather than --foo bar because the latter form would be ambiguous.
The following flags are defined.
There is another disadvantage of this flag: if the parser fails due to a missing option that was declared required, it is not possible to detect if other options were given. For example, if the suite defines the --help option, and the application is executed with this option only, the parser will still return a parse error.
Enumerable options take one out of a fixed set of possible values which are predefined in the suite. Such options are always of type string. It is an error if a different argument type was specified or if the option was defined to not take an argument.
The syntax for the array of values is
values = {ID_0 = "string_0", ..., ID_N = "string_N"}
For each option for which the values directive was specified, the lopsubgen command generates a C enumeration which contains the given identifiers. This allows referring to each possible value through a numeric constant.
If no default_val is specified in the suite, and the option is not given in the argument vector either, the implied value depends on the argument type. For numeric options, a value of zero is assumed. For options which take a string argument, a NULL pointer is returned. For enum options, the first possible value (index zero) is taken as the default.
A minimal suite and the corresponding "application".
The suite file hello.suite:
[suite hello] [supercommand hello] purpose = hello world [option world] summary = add "world"
The "application" hello.c:
#include <stdio.h> /* printf(3) */ #include <stdlib.h> /* exit(3) */ #include <lopsub.h> #include "hello.lsg.h" int main(int argc, char **argv) { struct lls_parse_result *lpr; const struct lls_opt_result *result; const struct lls_command *cmd = lls_cmd(0, hello_suite); int ret; ret = lls_parse(argc, argv, cmd, &lpr, NULL); if (ret < 0) { fprintf(stderr, "%s\n", lls_strerror(-ret)); exit(1); } printf("hello"); result = lls_opt_result(LSG_HELLO_HELLO_OPT_WORLD, lpr); if (lls_opt_given(result)) printf(" world"); printf("\n"); exit(0); }
Generate hello.lsg.c and hello.lsg.h:
$ lopsubgen --gen-c --gen-h < hello.suite
Compile hello.c and hello.lsg.c to produce the hello executable:
$ cc hello.c hello.lsg.c -o hello -llopsub
Run it:
$ ./hello hello $ ./hello --world hello world $ ./hello -w option not recognized $ ./hello 42 invalid number of arguments
Generate and examine the manual page:
$ lopsubgen --gen-man < hello.suite $ man -l ./hello.lsg.man
lopsubgen(1), lopsub(7), lopsubex(1), gengetopt(1), getopt(1), getopt(3)
May 2024 | 1.0.5 |