-
Notifications
You must be signed in to change notification settings - Fork 0
Response files
Sometimes it is convenient to provide command line arguments in a file and have it referenced from the real command line. You can think of it as similar to #include
contents of the file in your command line arguments. This approach is especially popular on Windows where command line is (or at least used to be) very limited in length. Thus, the only way to supply a lengthy command line there is to put it into a response file.
The way it works is that whenever a command line argument starts with a given prefix (the de-facto standard on Windows is @
) the rest of the argument is treated as a filename, the file is opened and its content is used instead. Details of how to split file content vary. Some utilities will treat each line as an argument, some will split each line on whitespace etc.
Following its modular architecture Argum provides support for response files via a separate ResponseFileReader
(and WResponseFileReader
) class. You use it as follows:
- Create an instance of
ResponseFileReader
giving it a prefix or prefixes to look for. - Call its
expand
method on a range of command line arguments. The range can beargc,argv
or a random access container or a range of things convertible tostd::string_view
- The
expand
method processes the arguments, locates response files, if present, and substitutes their content.- This is done recursively, that is a response file can reference another response file
- The output is
std::vector<std::string>
that can be directly passed toParser::parse
.
- You can optionally pass a
Splitter
object to theexpand
method. It will be used to decide how to split each response line into arguments.- By default, if you don't pass a splitter, each non empty line is trimmed of whitespace on both ends and used as a single argument
- The
Splitter
is function object that is invoked asvoid (string && line, auto dest)
. Thedest
argument is some kind of output iterator. You copy/move the produced strings into it.
- On any error locating or reading response files it throws
ResponseFileReader::Exception
derived fromParsingException
. Thusexpand
should be called within parsingtry
block.
Putting it all together here is an example using default splitter
Parser parser;
...
try {
parser.parse(ResponseFileReader('@').expand(argc, argv));
} catch (ParsingException & ex) {
cerr << ex.message() << '\n';
cerr << parser.formatUsage(progname) << '\n';
return EXIT_FAILURE;
}
And this is one where we split on whitespace
Parser parser;
...
regex whitespace("\\s+");
try {
parser.parse(ResponseFileReader('@').expand(argc, argv,
[&](string && line, auto dest){
copy(sregex_token_iterator(line.begin(), line.end(), whitespace, -1),
sregex_token_iterator(), dest);
}));
} catch (ParsingException & ex) {
cerr << ex.message() << '\n';
cerr << parser.formatUsage(progname) << '\n';
return EXIT_FAILURE;
}
- Home
-
Usage Guide
Basics
Error Handling
Thread Safety
Adding Help
Defining options
Positional arguments
Reporting errors from handlers
Parsing common data types
Validation
Depending on order
Subcommands
Response files
Partial Parsing -
Advanced
Syntax Description
Customizing syntax
Customizing usage and help
Localization