Difference between revisions of "The libshore C++ Library"
(→Adding command line options) |
(→Further documentation to be written.) |
||
(4 intermediate revisions by the same user not shown) | |||
Line 4: | Line 4: | ||
[http://shore.sourceforge.net/libshore-api/files.html Doxygen-generated API documentation] is available. | [http://shore.sourceforge.net/libshore-api/files.html Doxygen-generated API documentation] is available. | ||
− | + | = The ''program'' class = | |
− | The ''' ''program'' ''' class is a command line interface base class providing command line option parsing and documentation as well as application-level exception handling and reporting. | + | The [http://shore.sourceforge.net/libshore-api/classshore_1_1program.html ''' ''program'' ''' ] class is a command line interface base class providing command line option parsing and documentation as well as application-level exception handling and reporting. |
− | + | == Hello world == | |
// file hello_program.cpp | // file hello_program.cpp | ||
Line 57: | Line 57: | ||
Hello, world! | Hello, world! | ||
− | + | == Adding command line options == | |
Command line options and further usage instructions may be defined in the class's constructor. | Command line options and further usage instructions may be defined in the class's constructor. | ||
Line 83: | Line 83: | ||
virtual void sanity_check() | virtual void sanity_check() | ||
{ | { | ||
− | if(m_conf.name=="Joe") | + | if(m_conf.name == "Joe") |
throw usage_error("Joe is not around"); | throw usage_error("Joe is not around"); | ||
} | } | ||
Line 100: | Line 100: | ||
} | } | ||
}; | }; | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
+ | (the global ''main()'' function is omitted from now on) | ||
When called without command line options, the output is now | When called without command line options, the output is now | ||
Line 204: | Line 198: | ||
Furthermore, as shown in the example's constructor, ''shore::OPT_MANDATORY'' may be specified to instruct the command line option parser to automatically verify that an option was specified by the user: | Furthermore, as shown in the example's constructor, ''shore::OPT_MANDATORY'' may be specified to instruct the command line option parser to automatically verify that an option was specified by the user: | ||
− | $ ./hello -t 2 | + | $ ./hello -t 2 |
./hello --- Greeter program | ./hello --- Greeter program | ||
Line 216: | Line 210: | ||
error: need `--names' (mandatory) | error: need `--names' (mandatory) | ||
− | + | = Further documentation to be written. = |
Latest revision as of 19:59, 20 June 2013
Basic functionality used by SHORE is provided as a C++ programming library residing below the directory src/CoreLib of the SHORE source package. The make install command will by default install the libshore library and headers below /usr/local/lib and /usr/local/include, respectively; see the file INSTALL distributed with the SHORE sources for details.
Doxygen-generated API documentation is available.
Contents
The program class
The program class is a command line interface base class providing command line option parsing and documentation as well as application-level exception handling and reporting.
Hello world
// file hello_program.cpp #include <iostream> #include "shore/program/program.hpp" class hello_program :public shore::program { protected: virtual int main() { std::cout << "\nHello, world!\n" << std::endl; } }; int main(int ac, char **av) { hello_program p; p(ac, av); return p.status(); }
Given libshore is installed system-wide, this program may be compiled using the command
$ g++ -lshore -o hello hello_program.cpp
The default behavior of the program base class is to display usage instructions when no command line arguments are provided:
$ ./hello ./hello Usage: ./hello
However, the main() method is invoked if the command's input is a pipe:
$ true | ./hello Hello, world!
This default behavior is sensible for many applications. It may however be altered by overriding the protected base class method basic_sanity_check():
virtual void basic_sanity_check() {}
As a result, the default is no longer to display the help page:
$ ./hello Hello, world!
Adding command line options
Command line options and further usage instructions may be defined in the class's constructor.
For clarity, command line option variables are grouped in a struct config in our example.
For validation of provided user input, the protected base class method sanity_check() may be implemented.
Invalid user input is indicated by throwing an exception of class usage_error defined by the program class:
class hello_program :public shore::program { private: struct config { std::string name; }; config m_conf; protected: virtual void sanity_check() { if(m_conf.name == "Joe") throw usage_error("Joe is not around"); } virtual int main() { std::cout << "\nHello, " << m_conf.name << "!\n" <<std::endl; } public: hello_program() { set_description("Greeter program"); add_option("name,n", &m_conf.name, "The person to greet (but not Joe)"); } };
(the global main() function is omitted from now on)
When called without command line options, the output is now
$ ./hello ./hello --- Greeter program Usage: ./hello [OPTIONS] Allowed options: -n, --name=STRING (not set) The person to greet (but not Joe)
Command line options are automatically verified through sanity_check():
$ ./hello -n Jim Hello, Jim! $ ./hello -n Joe ./hello --- Greeter program Usage: ./hello [OPTIONS] Allowed options: -n, --name=STRING (=Joe) The person to greet (but not Joe) error: Joe is not around
Command line option variables are not restricted to the std::string class, but may be of any class for which an operator>> for std::istream objects is defined. Furthermore, certain classes such as std::vector<T> are handled explicitly by the command line option parser:
#include <iostream> #include <string> #include <vector> #include "shore/program/program.hpp" #include "shore/base/stringops.hpp" // for shore::join() and shore::to_string() class hello_program :public shore::program { private: struct config { std::vector<std::string> names; int times; }; config m_conf; protected: virtual void sanity_check() { if(m_conf.times < 1) throw usage_error("invalid value " + shore::to_string(m_conf.times) + " for --times"); } virtual int main() { for(int i = 0; i < m_conf.times; ++i) std::cout << "Hello, " << shore::join(m_conf.names, ", ") << '!' <<std::endl; } public: hello_program() { m_conf.times=1; set_description("Greeter program"); add_option("names,n", &m_conf.names, "The people to greet", shore::OPT_MANDATORY); add_option("times,t", &m_conf.times, "Greet multiple times"); } };
When correctly invoked, the example's output is
$ ./hello -t 2 -n Jim -n Joe Hello, Jim, Joe! Hello, Jim, Joe!
In this example, the sanity_check() method was changed to ensure correct specification of the --times option. Furthermore, the default value for times was set to 1 in the constructor, which is displayed accordingly in the middle column of the new help page:
$ ./hello ./hello --- Greeter program Usage: ./hello OPTIONS Allowed options: -n, --names=STRING[,...] (mandatory) The people to greet -t, --times=INT (=1) Greet multiple times
For options that do not have a default value, output of the default may be suppressed by specifying shore::OPT_NOTSET as an additional parameter to the add_option() method.
Furthermore, as shown in the example's constructor, shore::OPT_MANDATORY may be specified to instruct the command line option parser to automatically verify that an option was specified by the user:
$ ./hello -t 2 ./hello --- Greeter program Usage: ./hello OPTIONS Allowed options: -n, --names=STRING[,...] (mandatory) The people to greet -t, --times=INT (=2) Greet multiple times error: need `--names' (mandatory)