00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef GETOPT_HPP
00026 #define GETOPT_HPP
00027
00028
00029 #include <boost/shared_ptr.hpp>
00030 #include <boost/scoped_ptr.hpp>
00031 #include <iosfwd>
00032 #include <vector>
00033 #include <map>
00034 #include <string>
00035 #include <sstream>
00036
00037
00038 struct option;
00039
00040
00041 namespace util {
00042
00043
00044 class BaseCallback
00045 {
00046 public:
00047 BaseCallback(char shortopt,
00048 const char * longopt_name,
00049 bool requires_arg,
00050 const char * description);
00051 virtual ~BaseCallback();
00052 virtual bool Do(const char * arg, std::ostream & os) = 0;
00053
00054 const char m_shortopt;
00055 const std::string m_longopt_name;
00056 const bool m_requires_arg;
00057 const std::string m_description;
00058 boost::scoped_ptr<option> m_longopt;
00059 };
00060
00061
00062 class Parser
00063 {
00064 public:
00065 Parser()
00066 : m_longest_longopt(0)
00067 { }
00068
00071 bool Add(boost::shared_ptr<BaseCallback> callback);
00072
00075 bool Add(BaseCallback * callback)
00076 { return Add(boost::shared_ptr<BaseCallback>(callback)); }
00077
00083 int Do(int argc, char ** argv, std::ostream & os);
00084
00085 void UsageMessage(std::ostream & os);
00086
00087
00088 typedef std::map<char, unsigned int> index_map_t;
00089
00090 index_map_t m_index_map;
00091 std::vector<boost::shared_ptr<BaseCallback> > m_callback;
00092 std::vector<bool> m_present;
00093 std::vector<const char *> m_argument;
00094 unsigned int m_longest_longopt;
00095 };
00096
00097
00098 template<typename T>
00099 class Callback
00100 : public BaseCallback
00101 {
00102 public:
00103 typedef T option_t;
00104
00105 Callback(option_t & option,
00106 char shortopt,
00107 const char * longopt_name,
00108 const char * description)
00109 : BaseCallback(shortopt, longopt_name, true, description),
00110 m_option(option)
00111 { }
00112
00113 virtual bool Do(const char * arg, std::ostream & os) {
00114 if(arg == 0) {
00115 os << m_longopt_name << ": argument expected\n";
00116 return false;
00117 }
00118 std::istringstream is(arg);
00119 is >> m_option;
00120 if( ! is) {
00121 os << m_longopt_name << ": invalid argument \"" << arg << "\"\n";
00122 return false;
00123 }
00124 return true;
00125 }
00126
00127 option_t & m_option;
00128 };
00129
00130
00131 template<>
00132 class Callback<bool>
00133 : public BaseCallback
00134 {
00135 public:
00136 typedef bool option_t;
00137
00138 Callback(option_t & option,
00139 char shortopt,
00140 const char * longopt_name,
00141 const char * description)
00142 : BaseCallback(shortopt, longopt_name, false, description),
00143 m_option(option)
00144 { }
00145
00146 virtual bool Do(const char * arg, std::ostream & os) {
00147 m_option = true;
00148 return true;
00149 }
00150
00151 option_t & m_option;
00152 };
00153
00154 }
00155
00156 #endif // GETOPT_H