Even if this information is saved away, it should be mentioned that in C++ it is not possible to access a programs arguments, or the name of the program from any code which is run as a result of the creation of static objects. This is because these static objects may or may not be created before `main()' has commenced executing. If the code was run before `main()' had started executing, the information would not have yet been saved away so as to be available.
For those instances where it would be valid to access this information, a number of classes are provided to make access to the information consistent, and to also assist in manipulating that information. The class provided to assist in manipulating command line options, obtained from any source, is the OTC_Options class. The classes provided for making access to the programs arguments consistent are the OTC_Program and OUX_Program classes. The latter class extending the former to add support specific to the UNIX operating system.
For example, to initialise an instance of OTC_Options in `main()' with the programs arguments, you would write:
main(int argc, char* argv[])Note that the name of the program, stored in `argv[0]', is skipped as we are only interested in the arguments to the program.
{
OTC_Options pargs(argc-1,argv+1);
...
}
In the case of a initialising the OTC_Options class with a single string, the class will split the string into separate options using white space as the separator between options. If white space is significant, double quotes should be used to surround the option. Quotes will subsequently be dropped. If a real double quote is required, it should be preceded with the `\' character.
To access an option once the class has been initialised, the `option()' member function is used. When called, you must indicate the number of the option you want. Numbering for options starts at `1' and not at `0'. In addition to the `option()' member function you can access the options using an iterator. The iterator is obtained by calling the `options()' member function. Both methods are illustrated below.
int n = pargs.numOptions();The options may also be manipulated in a manner similar to what is possible from shell scripts. To do this, the `shift()' member function is used in conjunction with the `numOptions()' and `option()' member functions.
for (int i=1; i<=n; i++)
cout << pargs.option(i) << endl;
OTC_Iterator<OTC_String> iter = 0;
iter = pargs.options();
for (iter.reset(); iter.isValid(); iter.next())
cout << iter.item() << endl;
while (pargs.numOptions() != 0)If a particular option isn't specified, the `option()' member function will return the first option. The `restore()' member function is also provided so that options can be reset back to what they were before the `shift()' member function was called.
{
cout << pargs.option() << endl;
pargs.shift();
}
pargs.restore();
main(int argc, char* argv[])The OTC_Program class provides the same facilities as the OTC_Options class, except that all member functions are static. The OTC_Program class provides one additional facility to that of OTC_Options. This facility is the ability to match arguments using a glob style expression. This ability also borrows from what is possible within shell scripts.
{
OTC_Program::initialise(argc,argv);
...
}
void usage()
{
cerr << "Usage: "
<< OTC_Program::name()
<< " input [ output ]"
<< endl;
}
while (OTC_Program::numOptions() != 0)
{
if (OTC_Program::match("*.h"))
{
hdrs.addLast(OTC_Program::option());
}
else if (OTC_Program::match("-*"))
{
...
}
else
{
usage();
exit(1);
}
OTC_Program::shift();
}
OTC_Program::restore();
Depending on the environment in which the program was executed, the name of the program may or may not contain a directory component. When printing out messages in which the program name is displayed, we do not always want the directory component to be visible. In order to get the name of the program without the directory component, you need to use a version of OTC_Program for the specific type of operating system you are using. For the UNIX operating system you should use the OUX_Program class. The static member function of this class which returns the name of the program, with any directory component removed is `basename()'.
main(int argc, char* argv[])The directory component of the path to the program can be obtained using the `dirname()' member function of the OUX_Program class. Remember though, that the environment may not provide this and therefore and empty string or the current directory may be errornously returned.
{
OTC_Program::initialise(argc,argv);
...
}
void usage()
{
cerr << "Usage: "
<< OUX_Program::basename()
<< " input [ output ]"
<< endl;
}
The OUX_Program class need only be used to access the basename and directory part of the program. At other times, the OTC_Program class should be used. In future, the `basename()' and `dirname()' functions will most likely be pushed into OTC_Program with OUX_Program being eliminated. The implementations in OTC_Program will have compiled in whatever is appropriate to determine the results for the system the class is being used on.