Skip to content

Partial Parsing

gershnik edited this page Mar 16, 2022 · 6 revisions

Sometimes, when your command line utility wraps and invokes another, it's desirable to only partially parse command line. That is, to process arguments meant for your utility in the beginning of the command line and pass the rest to the wrapped one.

Argum supports this scenario via parseUntilUnknown method of the Parser class. Unlike regular parse it, as the name implies, successfully finishes parsing when it encounters an unknown option or an unexpected positional argument. The rest of the command line arguments are returned as std::vector<std::string>.

Note that apart from stopping at the unknown rather than throwing an exception parseUntilUnknown does everything else just like regular parse. This includes running validation on the arguments it processed.

Here is an example of a utility that does partial processing

bool all = false;
vector<string> remaining;

... 

parser.add(Option("-a").
            help("some kind of option").
            handler([&](){
    all = true;
}));
parser.add(
    Option("--help", "-h").
    help("show this help message and exit"). 
    handler([&]() {
        HelpFormatter fomatter(parser, progname);
        cout << fomatter.formatUsage() << " <other arguments>\n";
        cout << fomatter.formatHelp();
        exit(EXIT_SUCCESS);
}));

try {
    remaining = parser.parseUntilUnknown(ResponseFileReader('@').expand(argc, argv));
} catch (ParsingException & ex) {
    cerr << ex.message() << '\n';
    cerr << parser.formatUsage(progname) << " <other arguments>\n";
    return EXIT_FAILURE;
}

cout << "remaining: \"" << join(remaining.begin(), remaining.end(), " ") << "\"\n";

The results of running such code are:

$ ./prog --help
Usage: ./prog [-a] [--help] <other arguments>
options:
  -a          some kind of option
  --help, -h  show this help message and exit

$ ./prog       
remaining: ""
$ ./prog foo
remaining: "foo"
$ ./prog -a 
remaining: ""
$ ./prog -a -b foo
remaining: "-b foo"
$ ./prog -ab                                            
extraneous argument for option: -a
Usage: ./prog [-a] [--help] <other arguments>

Note the last output. When faced with -ab the parser cannot know whether it is user's attempt to pass an (invalid) argument b to option -a or two merged options -a and -b (the latter being unknown). It follows the first interpretation and reports an "extraneous argument" error. This is because it would be strange to merge both "outer" and "inner" arguments in the scenario of wrapped utility.

Also note the usage of HelpFormatter to format non-standard help message. More info about HelpFormatter can be found in Customizing usage and help page.