libshevek
|
00001 /* args.hh - argument parsing made easy 00002 * Copyright 2003-2010 Bas Wijnen <wijnen@debian.org> 00003 * 00004 * This program is free software: you can redistribute it and/or modify 00005 * it under the terms of the GNU General Public License as published by 00006 * the Free Software Foundation, either version 3 of the License, or 00007 * (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00016 */ 00017 00018 #ifndef SHEVEK_ARGS_HH 00019 #define SHEVEK_ARGS_HH 00020 00021 #include <getopt.h> 00022 #include <string> 00023 #include <vector> 00024 #include <list> 00025 #include <sigc++/sigc++.h> 00026 #include <glibmm/ustring.h> 00027 #include "debug.hh" 00028 00029 // Allow using this class without using automake. 00030 #ifndef PACKAGE_NAME 00031 #define PACKAGE_NAME "[name not defined]" 00032 #endif 00033 #ifndef PACKAGE_TARNAME 00034 #define PACKAGE_TARNAME PACKAGE_NAME 00035 #endif 00036 #ifndef PACKAGE_BUGREPORT 00037 #define PACKAGE_BUGREPORT "[bug report e-mail not defined]" 00038 #endif 00039 #ifndef PACKAGE_VERSION 00040 #define PACKAGE_VERSION "[version not defined]" 00041 #endif 00042 #ifndef COPYRIGHT_YEARS 00043 #define COPYRIGHT_YEARS "[no time of copyright defined]" 00044 #endif 00045 #ifndef COPYRIGHT_EMAIL 00046 #define COPYRIGHT_EMAIL "" 00047 #endif 00048 #ifndef COPYRIGHT_AUTHOR 00049 #define COPYRIGHT_AUTHOR "[no author defined]" 00050 #endif 00051 00052 namespace shevek 00053 { 00055 00065 class args 00066 { 00067 public: 00068 class option; 00071 args (int &argc, char **&argv, int min_args, int max_args, Glib::ustring const &description, 00072 /* The parameters below should always have their default values, 00073 * they are just here to get the #define'd values into the library. 00074 * The COPYRIGHT_* values should be defined in configure.ac 00075 */ 00076 Glib::ustring const ©right_years = COPYRIGHT_YEARS, 00077 Glib::ustring const ©right_email = (COPYRIGHT_EMAIL[0] == '\0' ? PACKAGE_BUGREPORT : COPYRIGHT_EMAIL), 00078 Glib::ustring const &programmer = COPYRIGHT_AUTHOR, 00079 Glib::ustring const &email = PACKAGE_BUGREPORT, 00080 char const *programname = PACKAGE_NAME, 00081 char const *packagename = PACKAGE_TARNAME, 00082 char const *version = PACKAGE_VERSION); 00084 template <unsigned size_> 00085 args (int &argc, char **&argv, option (&o)[size_], int min_args, 00086 int max_args, Glib::ustring const &description); 00088 unsigned size () const; 00090 std::string const &operator[] (unsigned idx) const; 00092 std::vector <std::string>::const_iterator begin () const; 00094 std::vector <std::string>::const_iterator end () const; 00095 private: 00096 std::vector <std::string> m_args; 00097 void l_setup (int &argc, char **&argv, option *o, unsigned num_options, 00098 int min_args, int max_args, 00099 Glib::ustring const &description, 00100 struct ::option *longopts, 00101 Glib::ustring const ©right_years = COPYRIGHT_YEARS, 00102 Glib::ustring const ©right_email = (COPYRIGHT_EMAIL[0] == '\0' ? PACKAGE_BUGREPORT : COPYRIGHT_EMAIL), 00103 Glib::ustring const &programmer = COPYRIGHT_AUTHOR, 00104 Glib::ustring const &email = PACKAGE_BUGREPORT, 00105 char const *programname = PACKAGE_NAME, 00106 char const *packagename = PACKAGE_TARNAME, 00107 char const *version = PACKAGE_VERSION); 00108 }; 00109 00111 class args::option 00112 { 00113 public: 00115 typedef sigc::slot1 <void, bool> callback0; 00117 typedef sigc::slot2 <void, bool, Glib::ustring const &> callback1; 00119 option (char shortopt, Glib::ustring const &longopt, Glib::ustring const &help_line, callback0 handle, bool *used = NULL); 00121 option (char shortopt, Glib::ustring const &longopt, Glib::ustring const &help_line, bool have_default, callback1 handle, Glib::ustring default_val = Glib::ustring (), bool *used = NULL); 00123 option (char shortopt, Glib::ustring const &longopt, Glib::ustring const &help_line, callback0 handle0, callback1 handle1, bool *used = NULL); 00125 option (char shortopt, Glib::ustring const &longopt, Glib::ustring const &help_line, bool &var, bool value, bool *used = NULL); 00127 option (char shortopt, Glib::ustring const &longopt, Glib::ustring const &help_line, bool have_default, Glib::ustring &var, bool *used = NULL); 00129 option (char shortopt, Glib::ustring const &longopt, Glib::ustring const &help_line, bool have_default, std::string &var, bool *used = NULL); 00131 option (char shortopt, Glib::ustring const &longopt, Glib::ustring const &help_line, bool have_default, unsigned long &var, bool *used = NULL); 00133 option (char shortopt, Glib::ustring const &longopt, Glib::ustring const &help_line, bool have_default, long &var, bool *used = NULL); 00135 option (char shortopt, Glib::ustring const &longopt, Glib::ustring const &help_line, bool have_default, unsigned &var, bool *used = NULL); 00137 option (char shortopt, Glib::ustring const &longopt, Glib::ustring const &help_line, bool have_default, int &var, bool *used = NULL); 00139 option (char shortopt, Glib::ustring const &longopt, Glib::ustring const &help_line, bool have_default, unsigned short &var, bool *used = NULL); 00141 option (char shortopt, Glib::ustring const &longopt, Glib::ustring const &help_line, bool have_default, short &var, bool *used = NULL); 00143 option (char shortopt, Glib::ustring const &longopt, Glib::ustring const &help_line, bool have_default, float &var, bool *used = NULL); 00145 option (char shortopt, Glib::ustring const &longopt, Glib::ustring const &help_line, bool have_default, double &var, bool *used = NULL); 00148 template <typename _T> option (char shortopt, Glib::ustring const &longopt, Glib::ustring const &help_line, std::list <_T> &list); 00149 private: 00150 friend class args; 00151 enum opt_t {NEED_ARG, NO_ARG, OPT_ARG}; 00152 void setup (char shortopt, Glib::ustring const &longopt, Glib::ustring const &help_line, bool have_default, opt_t have_arg, callback0 handle0, callback1 handle1, bool *used); 00153 void call (bool is_double, char const *optarg); 00154 char m_shortopt; 00155 Glib::ustring m_longopt; 00156 Glib::ustring m_help; 00157 bool m_have_default; 00158 Glib::ustring m_default; 00159 opt_t m_have_arg; 00160 callback0 m_handle0; 00161 callback1 m_handle1; 00162 bool *m_used; 00163 bool m_is_used; 00164 static void l_set (bool is_double, Glib::ustring const &arg, Glib::ustring *var); 00165 static void l_setstd (bool is_double, Glib::ustring const &arg, std::string *var); 00166 static void l_setint (bool is_double, Glib::ustring const &arg, int *var); 00167 static void l_setuint (bool is_double, Glib::ustring const &arg, unsigned *var); 00168 static void l_setlint (bool is_double, Glib::ustring const &arg, long *var); 00169 static void l_setulint (bool is_double, Glib::ustring const &arg, unsigned long *var); 00170 static void l_setsint (bool is_double, Glib::ustring const &arg, short *var); 00171 static void l_setusint (bool is_double, Glib::ustring const &arg, unsigned short *var); 00172 static void l_setbool (bool is_double, bool val, bool *var); 00173 static void l_setfloat (bool is_double, Glib::ustring const &arg, float *var); 00174 static void l_setdfloat (bool is_double, Glib::ustring const &arg, double *var); 00175 template <typename _T> 00176 static void l_setlist (bool is_double, Glib::ustring const &arg, std::list <_T> *list); 00177 }; 00178 00179 template <unsigned size_> args::args (int &argc, char **&argv, 00180 option (&o)[size_], 00181 int min_args, int max_args, 00182 Glib::ustring const &description) 00183 { 00184 startfunc; 00185 struct ::option longopts[size_ + 4]; 00186 l_setup (argc, argv, o, size_, min_args, max_args, description, longopts); 00187 } 00188 00189 00190 template <typename _T> 00191 args::option::option (char shortopt, Glib::ustring const &longopt, Glib::ustring const &help_line, std::list <_T> &list) 00192 { 00193 startfunc; 00194 setup (shortopt, longopt, help_line, false, NEED_ARG, callback0 (), 00195 sigc::bind (sigc::ptr_fun (&l_setlist <_T>), &list), NULL); 00196 } 00197 00198 template <typename _T> 00199 void args::option::l_setlist (bool is_double, Glib::ustring const &arg, std::list <_T> *list) 00200 { 00201 startfunc; 00202 list->push_back (_T () ); 00203 option tmp ('x', "x", "x", false, list->back () ); 00204 tmp.m_handle1 (false, arg); 00205 } 00206 } 00207 00208 #endif