Parsing Properties
The Properties
interface provides several operations for converting properties to and from command-line options.
On this page:
Converting Properties to Command-Line Options
The getCommandLineOptions
operation converts an initialized set of properties into a sequence of equivalent command-line options:
module Ice { local interface Properties { StringSeq getCommandLineOptions(); // ... } }
For example, if you have set the Filesystem.MaxFileSize
property to 1024 and call getCommandLineOptions
, the setting is returned as the string "--Filesystem.MaxFileSize=1024"
. This operation is useful for diagnostic purposes, for example, to dump the setting of all properties to a logging facility, or if you want to fork a new process with the same property settings as the current process.
Converting Command-Line Options to Properties
The parseCommandLineOptions
operation examines the passed argument vector for command-line options that have the specified prefix:
module Ice { local interface Properties { StringSeq parseCommandLineOptions(string prefix, StringSeq options); // ... } }
All options having the form --prefix.Key=Value
are converted to property settings (that is, they initialize the corresponding properties). The operation returns an argument vector containing the options that did not match the prefix.
The value for prefix
has an implicit trailing period if one is not present. For example, when calling parseCommandLineOptions
with a prefix value of "File"
, the option --File.Owner=root
would match but the option --Filesystem.MaxFileSize=1024
would not match.
The operation parses command-line options using the same syntax rules as for properties in a configuration file. However, the user's command shell can cause differences in parsing behavior. Suppose we define the following property in a configuration file:
MyApp.Home=C:\Program Files\MyApp
The presence of whitespace in the property definition is not an issue in a configuration file but can be an issue on the command line, where the equivalent option is --MyApp.Home=C:\Program Files\MyApp
. If the user is not careful, the program may receive this as two separate options: --MyApp.Home=C:\Program
and Files\MyApp
. In the end, it is the user's responsibility to ensure that the property's complete key and value are contained within a single command-line option.
C++ Helper Functions
Because parseCommandLineOptions
expects a sequence of strings while C++ programs are used to dealing with argc
and argv
, Ice provides two utility functions that convert an argc
/argv
vector into a sequence of strings and vice-versa:
namespace Ice { // Ice::StringSeq is a std::vector<std::string> // StringSeq argsToStringSeq(int argc, const char* const argv[]); void stringSeqToArgs(const StringSeq& args, int& argc, const char* argv[]); inline void stringSeqToArgs(const StringSeq& seq, int& argc, char* argv[]) { // adapts the argv parameter return stringSeqToArgs(seq, argc, const_cast<const char**>(argv)); } }
You need to use parseCommandLineOptions
(and the utility functions) if you want to permit application-specific properties to be set from the command line. For example, to allow the --Filesystem.MaxFileSize
option to be used on the command line, we need to initialize our program as follows:
int main(int argc, char* argv[]) { // Create an empty property set. // auto props = Ice::createProperties(); // Convert argc/argv to a string sequence. // auto args = Ice::argsToStringSeq(argc, argv); // Strip out all options beginning with --Filesystem. // args = props->parseCommandLineOptions("Filesystem", args); // args now contains only those options that were not // stripped. Any options beginning with --Filesystem have // been converted to properties. // Convert remaining arguments back to argc/argv vector. // Ice::stringSeqToArgs(args, argc, argv); // Initialize communicator. // Ice::InitializationData initData; initData.properties = props; Ice::CommunicatorHolder ich(argc, argv, id); // At this point, argc/argv only contain options that // set neither an Ice property nor a Filesystem property, // so we can parse these options as usual. // // ... }
int main(int argc, char* argv[]) { // Create an empty property set. // Ice::PropertiesPtr props = Ice::createProperties(); // Convert argc/argv to a string sequence. // Ice::StringSeq args = Ice::argsToStringSeq(argc, argv); // Strip out all options beginning with --Filesystem. // args = props->parseCommandLineOptions("Filesystem", args); // args now contains only those options that were not // stripped. Any options beginning with --Filesystem have // been converted to properties. // Convert remaining arguments back to argc/argv vector. // Ice::stringSeqToArgs(args, argc, argv); // Initialize communicator. // Ice::InitializationData initData; initData.properties = props; Ice::CommunicatorHolder ich(argc, argv, id); // At this point, argc/argv only contain options that // set neither an Ice property nor a Filesystem property, // so we can parse these options as usual. // // ... }
Using this code, any options beginning with --Filesystem
are converted to properties and are available via the property lookup operations as usual. The call to initialize
made by the CommunicatorHolder
constructor removes any Ice-specific command-line options so, once the communicator is created, argc
/argv
only contains options and arguments that are not related to setting either a filesystem or an Ice property.
An easier way to achieve the same thing is to use a CommunicatorHolder
constructor that accepts a string sequence, instead of an argc
/argv
pair:
int main(int argc, char* argv[]) { // Create an empty property set. // auto props = Ice::createProperties(); // Convert argc/argv to a string sequence. // auto args = Ice::argsToStringSeq(argc, argv); // Strip out all options beginning with --Filesystem. // args = props->parseCommandLineOptions("Filesystem", args); // args now contains only those options that were not // stripped. Any options beginning with --Filesystem have // been converted to properties. // Initialize communicator. // Ice::InitializationData initData; initData.properties = props; Ice::CommunicatorHolder ich(args, initData); // At this point, args only contains options that // set neither an Ice property nor a Filesystem property, // so we can parse these options as usual. // // ... }
int main(int argc, char* argv[]) { // Create an empty property set. // Ice::PropertiesPtr props = Ice::createProperties(); // Convert argc/argv to a string sequence. // Ice::StringSeq args = Ice::argsToStringSeq(argc, argv); // Strip out all options beginning with --Filesystem. // args = props->parseCommandLineOptions("Filesystem", args); // args now contains only those options that were not // stripped. Any options beginning with --Filesystem have // been converted to properties. // Initialize communicator. // Ice::InitializationData initData; initData.properties = props; Ice::CommunicatorHolder ich(args, initData); // At this point, args only contains options that // set neither an Ice property nor a Filesystem property, // so we can parse these options as usual. // // ... }
Converting Reserved Command-Line Options to Properties
The parseIceCommandLineOptions
operation behaves like parseCommandLineOptions
, but removes the reserved Ice-specific options from the argument vector:
module Ice { local interface Properties { StringSeq parseIceCommandLineOptions(StringSeq options); // ... } }
This operation is also used internally by the Ice run time to parse Ice-specific options in initialize
.