ROSE  0.9.10.91
Classes | Functions | Variables
Rose::CommandLine Namespace Reference

Description

Command line parsing.

This namespace encapsulates those things necessary for parsing the command-line for a ROSE-based tool. Command-lines consist of switches and their arguments, and positional arguments. The command-line parsers in this class are mainly for parsing the switches and their arguments, while the remaining non-switch, positional arguments can be retreived for parsing in a per-tool specific manner.

Command-line switches consist of an introductory sequence of characters (usually a hyphen or two) followed by the switch name. If the switch takes an argument (or arguments), that argument can be specified either as a separate entry in the program argument list (usually "argv") or separated from the switch name with an equal sign. On Unix systems, switches can also be single letters, can nestle together, and can take arguments either in the same argv entry or in the following entry.

Related switches are collected into switch groups which also have names. The name of the group is usually precedes the switch name and is separated from it by a colon. Group names are optional on the command-line if the switch name is unambiguous.

All of these behaviors can be adjusted using the underlying Sawyer::CommandLine API.

Parsers come in two flavors. The first flavor, "normal parsers", are suitable for programs that are able to define all their legal switches. They parse command-line switches and until they get to the first positional argument, or they can be configured to collect and skip over the positional arguments if desired.

The second flavor of parser, a "parser stage", is for programs that are unable or unwilling to define all their switches. In this mode, if a program argument has a prefix (e.g., "-") that looks like a switch but hasn't been defined as one, then it's considered to be an unrecognized switch and that single program argument is consumed and stored in an unrecognized switches list. Note that this is not a rigorous way to parse command-lines since the parser has no knowledge of how many arguments a switch takes. For instance, if "-log" is a valid, defined switch that takes one argument, and "-yaxis" is undefined but takes as an argument a sign ("+" or "-") followed by the word "linear" or "log", then the command "a.out -yaxis -log foo bar" will be parsed as having an undefined switch "-yaxis" followed by the switch "-log" whose argument is "foo", followed by one positional argument "bar". The correct parsing, had yaxis been defined, would have been switch "-yaxis" whose argument is "-log" followed by two positional arguments "foo" and "bar".

This API is part of the ROSE library and can call any functions in the ROSE library. See also, CommandlineProcessing, which has only lower-level functions that cannot call other parts of the ROSE library.

Classes

struct  GenericSwitchArgs
 Type for storing generic switch arguments. More...
 
class  SelfTest
 Base class for self tests. More...
 

Functions

ROSE_DLL_API Sawyer::CommandLine::Parser createEmptyParser (const std::string &purpose, const std::string &description)
 Empty command-line parser. More...
 
ROSE_DLL_API Sawyer::CommandLine::Parser createEmptyParserStage (const std::string &purpose, const std::string &description)
 Empty command-line parser suitable for use with other parsers. More...
 
ROSE_DLL_API Sawyer::CommandLine::SwitchGroup genericSwitches ()
 Generic command-line components. More...
 
ROSE_DLL_API void insertBooleanSwitch (Sawyer::CommandLine::SwitchGroup &, const std::string &switchName, bool &storageLocation, const std::string &documentation)
 Convenience for for adding Boolean switches. More...
 
ROSE_DLL_API void runSelfTestsAndExit ()
 Runs the self tests and then exits the program. More...
 
template<class SelfTest >
void insertSelfTest ()
 Convenient way to add a command-line self test. More...
 

Variables

ROSE_DLL_API GenericSwitchArgs genericSwitchArgs
 Global location for parsed generic command-line switches. More...
 
ROSE_DLL_API std::vector< SelfTest::PtrselfTests
 Collection of self tests to be run by –self-tests switch. More...
 

Function Documentation

ROSE_DLL_API Sawyer::CommandLine::Parser Rose::CommandLine::createEmptyParser ( const std::string &  purpose,
const std::string &  description 
)

Empty command-line parser.

Returns a command-line parser that has no switch declarations, but is set up consistently for ROSE tools. The purpose should be an uncapitalized, short, single-line string that appears near the top of the man page. The description can be much longer, multiple paragraphs, free-format, with Sawyer markup. It will appear under the heading "Description" in the man page.

See also, createEmptyParserStage.

ROSE_DLL_API Sawyer::CommandLine::Parser Rose::CommandLine::createEmptyParserStage ( const std::string &  purpose,
const std::string &  description 
)

Empty command-line parser suitable for use with other parsers.

Returns a command-line parser that has no switch declarations, but is set up consistently for ROSE tools. The parser is configured to skip over any program arguments it doesn't recognize, with the assumption that those arguments will be passed to another parser. This also means that this parser cannot report errors for misspelled or misused switches because it cannot tell whether the switch is misspelled or simply intended for the next parser.

The purpose should be an uncapitalized, short, single-line string that appears near the top of the man page. The description can be much longer, multiple paragraphs, free-format, with Sawyer markup. It will appear under the heading "Description" in the man page.

See also, createEmptyParser, genericSwitches.

ROSE_DLL_API Sawyer::CommandLine::SwitchGroup Rose::CommandLine::genericSwitches ( )

Generic command-line components.

Returns a description of the switches that should be available for all ROSE tools. For consistency's sake, most tools will want to have at least this set of switches which is intended to be common across all tools. These switches fall into some categories:

  • Actions: switches that cause some special action to be performed such as showing the documentation or version number, or running self-tests. If such a switch is specified, its action is performed instead of the tools normal action.
  • Adjustments: switches that cause a tool-wide adjustment in behavior, such as how internal program logic errors are handled or what diagnostic facilities are enabled.
  • Defaults: switches that provide default values for multiple software components, such as the maximum number of threads that a parallel analysis can use, or the name of the default SMT solver connection. These defaults are generic in the sense that they don't prescribe requirements for all components–they only provide defaults for those components that don't otherwise have a command-line setting.

To make a command-line parser that recognizes these switches, add the switches to the parser using its with method. For example, here's how to construct a parser that recognizes only these switches:

parseCommandLine(int argc, char *argv[]) {
Sawyer::CommandLine::Parser parser = CommandlineProcessing::createEmptyParser(purpose, description);
return parser
.with(CommandlineProcessing::genericSwitches()) // these generic switches
.with(mySwitches) // my own switches, etc.
.parse(argc, argv) // parse without side effects
.apply(); // apply parser results
}

In general, we want all tools to have all these switches. At a minimum, a tool developer should be aware that the switches in this group are in some sense reserved across all tools and should not be circumvented for other purposes. However, if a tool doesn't use a switch, the developer can remove that switch from the parser and its documentation in order to prevent user confusion. Here's an example of removing the "--threads" switch from a parser for a tool that doesn't support multiple threads:

Sawyer::CommandLine::Parser p = createParser(purpose, description).with(genericSwitches());
p.removeMatchingSwitch("--threads=1"); // must parse

If you encounter strange errors near this call, make sure you're using -pthread consistently in your compile and link commands. Its presence or absence should be the same as however the ROSE library itself was compiled and linked. Mixing up the -pthread switch creates ABI incompatibilities that manifest themselves in various ways that usually look like a problem with a function that's called from a program that uses librose: often a segmentation fault, but can also be hangs, incorrect results, etc. Note that -pthread is both a compile and a link switch.

See any recent tool for more examples.

See also, createEmptyParser, createEmptyParserStage.

ROSE_DLL_API void Rose::CommandLine::insertBooleanSwitch ( Sawyer::CommandLine::SwitchGroup ,
const std::string &  switchName,
bool &  storageLocation,
const std::string &  documentation 
)

Convenience for for adding Boolean switches.

Adds "--foo" (if switchName is "foo") and "--no-foo" to the specified switch group. The storage location's lifetime must extend to the point where the command-line is parsed. This function adds additional documentation describing how to disable the switch using "--no-foo" and what the default is (current value of storage location).

An alternative is to use a switch that takes a Boolean argument (e.g., "--foo=yes" or "--foo=no"), but this is more difficult for users to remember and type than just "--foo" and "--no-foo".

See also, createEmptyParser, createEmptyParserStage.

ROSE_DLL_API void Rose::CommandLine::runSelfTestsAndExit ( )

Runs the self tests and then exits the program.

Sequentially runs the self tests in selfTests and then exits. Exit status is success if and only if no test returns false. Tests that are null pointers are ignored.

template<class SelfTest >
void Rose::CommandLine::insertSelfTest ( )

Convenient way to add a command-line self test.

Definition at line 197 of file roseSupport/CommandLine.h.

Variable Documentation

ROSE_DLL_API GenericSwitchArgs Rose::CommandLine::genericSwitchArgs

Global location for parsed generic command-line switches.

This global variable holds the results of command-line parsing using genericSwitches. Normally these settings are passed per command-line parsing request, but the interface in ROSE doesn't have that ability yet, so we use a global variable.

See also, genericSwitches.

Referenced by Rose::BinaryAnalysis::InstructionSemantics2::LlvmSemantics::Transcoder::instanceX86().

ROSE_DLL_API std::vector<SelfTest::Ptr> Rose::CommandLine::selfTests

Collection of self tests to be run by –self-tests switch.

The unit tests are run sequentially from first to last, optionally stopping at the first test that fails. Null pointers are ignored without causing any failure.