Skip to content

Yocto/Cli: Utilities for writing command-line apps

Yocto/Cli is a collection of utilities used in writing command-line applications, including parsing command line arguments, printing values, and timers. Yocto/Cli is implemented in yocto_cli.h.

Printing values

Use print_info(message) to print a message, and print_error(message) to print an error. To time a block of code create a simple_timer and get the elapsed time with elapsed_format(timer).

print_info("Message");          // print message
print_fatal("Error and exit");  // print error and exit
auto timer = simple_timer{};    // start timer
print_info("elapsed: {}",       // print elapsed time
  elapsed_formatted(timer));

Command-Line Parsing

Yocto/Cli includes a simple command-line parser that supports optional arguments with automatic help generation and error checking. This parser is meant to be simple and force a command-line style where an app has several commands, all of which are options with default values.

The command-line parser is initialized with make_cli(name, help) that takes a program name and a help string. Then add command-line options with add_option(cli, name, value, help, check) for optional arguments. In these commands, name is the option name, value is a reference to the variable that we want to set, help is a usage message, and check is either a range of valid values er a list of valid choices. A help flag is automatically added.

The command line is parsed for options named -- followed by the option name. The type of each option is determined by the passed reference. The parser supports integers, floating point numbers, strings, boolean flags, enums, arrays and vectors.

After adding all arguments, use ok = parse_cli(cli, args, error) to parse the command-line. If an error occurs, the parser throws false and stores in error a message that can be printed to inform the user. You can also use parse_cli(cli, args) in which case a cli_error exception is thrown if errors occur.

auto samples = 10; auto flag = false;                // state
auto out = ""s, scene = ""s;
auto scenes = vector<string>{};
auto cli = make_cli("app", "testing cli");      // initialize cli
add_option(cli, "out", out, "out");             // optional argument
add_option(cli, "samples", samples, "samples"); // optional argument
add_option(cli, "flag", flag, "flag");          // optional flag
add_argument(cli, "scene", scene, "scene");     // positional argument
add_option(cli, "scenes", scenes, "scenes");    // positional arguments
auto args = make_cli_args(argc, argv);          // make a vector of args
auto error = string{};                          // error string
if (!parse_cli(cli, args, error))               // parse args
  print_error(error);                           // print error
try {
  parse_cli(cli, args);                         // parse args
} catch(const cli_error& error) {
  print_error(error);                           // print error
}

Command-Line Commands

The command line parser also support commands, that are created by add_command(cli, name, help), where name is the command name and help is the command usage message. You can add options to commands using the functions above. Commands can have any optional arguments, but support either sub-commands or positional arguments. To get the selected command, set a string variable with set_command_var(cli, var) that will receive the command name.

auto samples = 10; auto scene = ""s;                // state
auto command = string{};                            // selected command 
auto cli = make_cli("app", "testing cli");          // initialize cli
set_command_var(cli, command);                      // command variable
auto render = add_command(cli, "render", "render"); // command
add_option(render, "samples", samples, "samples");  // optional argument
add_argument(render, "scene", scene, "scene");      // positional argument
auto convert = add_command(cli, "convert", "convert"); // command
add_argument(convert, "scene", scene, "scene");     // positional argument
parse_cli(cli, make_cli_args(argc, argv));          // parse cli
if (command == "render") { ... }                    // execute commands
else if (command == "samples") { ... }

Command-Line JSON Serialization

Command-line arguments can be loaded from JSON config files by specifying the --config <filename> option in the command line. The semantic of the config file is that configs are loaded first, and then overridden by the value specified in the terminal.

The JSON file should contain a value for each specified option, of the same type as the option itself. For commands, use a JSON object to specify their values. The command variable is called command.

Alternatively, you can specify an option that, if specified, indicates a filename in a directory where the config might be found, using add_option_with_config(cli, name, value, usage, config, alt). Here config is the filename of the optional config file.