lopsub-suite(5)
π lopsub-suite β the lopsub suite syntax, explained by your favorite Unix bestie π
okay so. bestie. this is lopsub-suite, it lives in section 5 of the manual (File Formats Manual), and it's literally the whole tea on how to write a lopsub suite. no cap.
β¨ NAME β¨
lopsub-suite β the syntax of a lopsub suite π«Ά
πΈ DESCRIPTION πΈ
okay so picture this: a lopsub suite describes all the options to a command line utility that has zero or more related subcommands. iconic setup, honestly.
The lopsubgen(1) utility is the queen that 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 the subcommands defined in the suite. slay.
This document explains the format of a lopsub suite. the overall structure is literally this:
[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 β everything from there 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 the 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, bestie.
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. main character behavior fr fr.
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. so fancy.
Empty lines and lines starting with a hash character ( # ) are ignored. π
π SUITE DIRECTIVES π
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. iykyk.
captionβ the optional text for an unnumbered section heading at the beginning of the manual page. β¨titleβ sets the title of the man page. defaults to the name of the supercommand. if this is not given and the suite has no supercommand, the.THmacro to set the title of the man page is omitted. π«Άmansectβ sets the man page section. defaults to1(user commands). bothtitleandsectionare positioned at the left and right in the header line. πdateβ this text is positioned in the middle of the footer line of the man page. it is common to set this to the date of the last nontrivial change that was made to the man page. defaults to the current date. ποΈversion-stringβ positioned at the left in the footer line. defaults to the empty string. the value of this directive is ignored if a version string is explicitly requested by passing--version-stringtolosubgen. (yes, that's spelledlosubgenin the source β copying it exactly, don't come for me π)manual_titleβ centered in the header line. defaults to"User commands". πΈintroduction,conclusionβ the text enclosed between[introduction]and[/introduction]is shown between the supercommand (if any) and the subcommand list. concluding remarks after the subcommand list may be added in the same way with[conclusion]and[/conclusion]. both texts will become part of the manual page, but are not not part of the short or long help. π¦aux_info_prefixβ this text is shown at the bottom of each command before the value of theaux_infodirective. if noaux_infois specified for a command, the prefix is omitted as well. ifaux_info_prefixis not given, the empty string is assumed. πaux_info_defaultβ this text is only used for header output. the argument for the generated macro call is set to this value for all commands for which noaux_infodirective is given. if noaux_info_defaultdirective is given, the value0is used as the argument for the macro. π
π COMMAND DIRECTIVES π
purposeβ a single line containing the purpose of the command. this text is printed in the short and long help, and is also included in the man page. πdescription,closingβ arbitrary plain text enclosed between[description]and[/description]. the text may be split over multiple lines and paragraphs. the description of the supercommand (if any) becomes the description of the manual page, which is shown after the command summary and before the list of options. the descriptions of all commands are included in the manual page and in the long help text but not in the short help. π
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. πΈ
synopsisβ custom synopsis of the command. if this is not given, the synopsis text will be auto-generated from the options and the value of thenon-opts-namedirective. β¨non-opts-nameβ name of the command line arguments which are not related to any option, for example file names. this text will be included in the automatically generated synopsis text. π«Ά
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. π
aux_infoβ this directive is special because its value is not included in the generated.cfile but in the header file. more precisely, the preprocessor macroLSG_SUITENAME_AUX_INFOSwill be defined which expands to a series of macro calls toLSG_SUITENAME_AUX_INFO(val_n), one for each command of the suite, whereval_nis the (unquoted) value of theaux_infodirective of the *n*th command. commands for which noaux_infodirective was specified receive a value ofzero. theLSG_SUITENAME_AUX_INFOmacro is supposed to be defined by the application. hence it is up to the application to make the expansion ofLSG_SUITENAME_AUX_INFOSa valid C construct. π
The value, if specified, is also copied to the man page at the end of the section for the command. π
π okay that's part 1 bestie! there's more coming, don't go anywhere π
π OPTION DIRECTIVES π
okay bestie this is the good part β this is where you tell lopsub what each option actually is. Every directive down here describes one thing about an option inside an [option β¦] section. slay.
β¨ short_opt
The optional single-letter equivalent for the option, basically its little nickname. If you set this, the option can be given either in the GNU-style long option format with two leading dashes or in the short form with a single dash. If you don't set it, only the long form gets accepted, no cap. And as usual, multiple short option flags may be combined β so be messy with it, it's fine.
β¨ summary
A single line that summarizes the option. This text shows up in both the short and the long help and in the man page. Defaults to the empty string. keep it punchy.
β¨ typestr
A description of the type of the values for the option. Whatever text you give here gets printed in the synopsis of the command, which is part of the short help, the long help, and the man page. It defaults to the string "val".
heads up: this directive is ignored for flag options (options without an argument). so don't waste your time, it's giving nothing there π
β¨ arg_info
This one decides whether the option takes an argument at all. Possible values:
no_argrequired_argoptional_arg
which mean, respectively: takes no argument at all, takes an argument that is mandatory, or takes an argument that may be omitted. The default value is no_arg. So an option works as a flag if you just don't give the arg_info directive. iconic default behaviour honestly.
π¨ warning bestie: arguments to options which take an optional argument must be given as--foo=barrather than--foo barbecause the latter form would be ambiguous. yes really. it's giving chaos otherwise.
β¨ arg_type
For flag options this directive should be set to none, or not set at all. For options which take an argument, the value of the directive determines the type of that argument. Possible values are string for options which take a string argument, and int32, uint32. int64, uint64, for options which take a numeric argument. pick your fighter.
β¨ flag
Lopsub maintains for each option a bitmask which contains the value of each possible flag for this option. Flags may be accumulated by defining multiple flag directives in the suite. and ngl, note there is no equal sign between the flag directive and its value. it's just vibes, no =.
The following flags are defined:
πΈ multiple
This flag instructs the lopsub library to keep track of all given arguments to an option, not just one as for ordinary options. This is only relevant for options which take an (optional or required) argument. hoarding your args? valid.
πΈ required
Instruct the parser to fail if this option is not given in the argument vector. If an option may be given at the command line or in the config file, this flag should be avoided, because the command line argv vector will not be parsed successfully if the option is only given in the config file. The recommended way to deal with this situation is to parse command line and config file separately, then merge the two parse results and check in the application if the option is given in the merged parse result.
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. π yeah. it's like that.
πΈ ignored
This flag indicates that the current option is in fact not a real option. In particular, name and short_opt are both ignored. The purpose of this flag is to add additional information for the help output and the man page. a fake option for β¨aestheticβ¨ purposes only, essentially.
β¨ values
Create an enumerable option.
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. so don't try it, it will simply Not Work.
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. cute and useful, we stan.
β¨ default_val
This directive makes only sense for options which take an argument. For such options it defines the value the option parser provides automatically if the option is not given in the argument vector. the backup plan. the safety net. the emotional support value.
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
NULLpointer is returned. - For enum options, the first possible value (index zero) is taken as the default.
β¨ help
The detailed, multi-line help text for the current option. Included in the man page and the long help. this is your moment. write the essay. go off. π
π EXAMPLE π
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
π SEE ALSO π
lopsubgen(1)lopsub(7)lopsubex(1)gengetopt(1)getopt(1)getopt(3)
and that's the whole page bestie!! π«Ά this lil cutie is version 1.0.5-3.1build1 and it's dated February 2026 β love that for us. now go write some absolutely unhinged suites, you've got this. mwah πβ¨
π¦ where this page comes from
- ubuntu resolute: liblopsub-dev 1.0.5-3.1build1
- ubuntu stonking: liblopsub-dev 1.0.5-3.1build1
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms