Skip to content

Depending on order

gershnik edited this page Mar 14, 2022 · 4 revisions

It is important to understand that invocation of handlers for options and positional arguments is done sequentially as they are parsed. You can use this fact to make semantics of command arguments dependent on their order.

Consider a utility that accepts a list of files on command line to do something with. What needs to be done is affected by options. It is customary (e.g. as done by many compilers and linkers) in this case to have options apply only to files that follow them. This way user can specify different options for different files. Doing it with Argum is straightforward

string currentEncoding = "utf8";
vector<pair<filesystem::path, string>> filesWithEncoding;

...

parser.add(
    Positional("file").
    help("file to operate on").
    handler([&](const string_view & value) { 
        files.emplace_back(value, currentEncoding);
}));
parser.add(
    Option("--encoding", "-e").
    help("assume this encoding for the files that follow").
    handler([&](const string_view & value) { 
        currentEncoding = value;
}));

Each time --encoding option is invoked it changes the currentEncoding which is used to populate subsequent entries for files.

This is the most straightforward application of sequential nature of parsing. There is much more that can be done because parser definitions themselves can be modified in a handler affecting how subsequent arguments will be processed. This is described in Subcommands page.