| 1 | /*! |
|---|
| 2 | * \file |
|---|
| 3 | * \brief Definition of an argument parser class |
|---|
| 4 | * \author Thomas Eriksson, Pal Frenger and Johan Bergman |
|---|
| 5 | * |
|---|
| 6 | * Thanks to Svante Signell for valuable input |
|---|
| 7 | * |
|---|
| 8 | * ------------------------------------------------------------------------- |
|---|
| 9 | * |
|---|
| 10 | * IT++ - C++ library of mathematical, signal processing, speech processing, |
|---|
| 11 | * and communications classes and functions |
|---|
| 12 | * |
|---|
| 13 | * Copyright (C) 1995-2007 (see AUTHORS file for a list of contributors) |
|---|
| 14 | * |
|---|
| 15 | * This program is free software; you can redistribute it and/or modify |
|---|
| 16 | * it under the terms of the GNU General Public License as published by |
|---|
| 17 | * the Free Software Foundation; either version 2 of the License, or |
|---|
| 18 | * (at your option) any later version. |
|---|
| 19 | * |
|---|
| 20 | * This program is distributed in the hope that it will be useful, |
|---|
| 21 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 22 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 23 | * GNU General Public License for more details. |
|---|
| 24 | * |
|---|
| 25 | * You should have received a copy of the GNU General Public License |
|---|
| 26 | * along with this program; if not, write to the Free Software |
|---|
| 27 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
|---|
| 28 | * |
|---|
| 29 | * ------------------------------------------------------------------------- |
|---|
| 30 | */ |
|---|
| 31 | |
|---|
| 32 | #ifndef PARSER_H |
|---|
| 33 | #define PARSER_H |
|---|
| 34 | |
|---|
| 35 | // #define MAX_STR_LEN 4096 |
|---|
| 36 | |
|---|
| 37 | #include <itpp/base/vec.h> |
|---|
| 38 | #include <itpp/base/mat.h> |
|---|
| 39 | #include <itpp/base/array.h> |
|---|
| 40 | #include <iostream> |
|---|
| 41 | |
|---|
| 42 | |
|---|
| 43 | namespace itpp { |
|---|
| 44 | |
|---|
| 45 | /*! |
|---|
| 46 | \addtogroup parser |
|---|
| 47 | |
|---|
| 48 | \brief Argument Parser |
|---|
| 49 | \author Thomas Eriksson and Pal Frenger (Thanks to Svante Signell for |
|---|
| 50 | valuable input), modifications by Johan Bergman |
|---|
| 51 | |
|---|
| 52 | This class parses strings to variables. The syntax is compatible with Matlab |
|---|
| 53 | and Octave. It can be used in several different ways. The following test |
|---|
| 54 | program and test data file gives several examples: |
|---|
| 55 | |
|---|
| 56 | <ul> |
|---|
| 57 | <li> Use the Parser class on a parameter file </li> |
|---|
| 58 | <li> Use the Parser class on the command line input </li> |
|---|
| 59 | <li> Use the Parser class on a char pointer (usually the command line input) </li> |
|---|
| 60 | <li> Use the Parser class on a parameter file and a char pointer </li> |
|---|
| 61 | <li> Use the Parser class on an Array of strings </li> |
|---|
| 62 | <li> Use the Parser::get() method on a parameter file </li> |
|---|
| 63 | <li> Use the Parser::exist() method to check if variables exist </li> |
|---|
| 64 | </ul> |
|---|
| 65 | |
|---|
| 66 | The test program looks as follows: |
|---|
| 67 | \include parser_test.cpp |
|---|
| 68 | |
|---|
| 69 | The data file \c parser_test_data.txt looks as follows: |
|---|
| 70 | \include parser_test_data.txt |
|---|
| 71 | |
|---|
| 72 | Beside the type-specific get methods, like get_int(), there is a templated |
|---|
| 73 | get method called get(), that can handle all variable types that have an |
|---|
| 74 | istream operator defined, e.g. Arrays. The get() method takes the variable |
|---|
| 75 | value as an input/output parameter. If the variable name cannot be found, |
|---|
| 76 | the old value is kept. Here is an example: |
|---|
| 77 | |
|---|
| 78 | \code |
|---|
| 79 | // Declare and initialize a variable |
|---|
| 80 | Array<ivec> var; |
|---|
| 81 | set_array(var, "{[1] [2 3] [4 5 6]}"); |
|---|
| 82 | |
|---|
| 83 | // Let the Parser p get the variable named my_var_name |
|---|
| 84 | bool my_var_name_was_found = p.get(var, "my_var_name"); |
|---|
| 85 | \endcode |
|---|
| 86 | |
|---|
| 87 | In the above example, if \c my_var_name was not found, \c var keeps its old |
|---|
| 88 | value {[1] [2 3] [4 5 6]}. In non-silent mode, the get() method echoes the |
|---|
| 89 | variable values to the standard output in Matlab/Octave m-file style. |
|---|
| 90 | */ |
|---|
| 91 | |
|---|
| 92 | /*! |
|---|
| 93 | \ingroup parser |
|---|
| 94 | \brief Argument Parser Class |
|---|
| 95 | \author Thomas Eriksson and Pal Frenger (Thanks to Svante Signell for |
|---|
| 96 | valuable input) |
|---|
| 97 | |
|---|
| 98 | This class parses strings to variables. The syntax is compatible with Matlab |
|---|
| 99 | and Octave. It can be used in several different ways. See the Detailed Description |
|---|
| 100 | in the \ref parser module. |
|---|
| 101 | */ |
|---|
| 102 | class Parser { |
|---|
| 103 | public: |
|---|
| 104 | |
|---|
| 105 | //! Default Constructor |
|---|
| 106 | Parser(); |
|---|
| 107 | |
|---|
| 108 | //! Constructor. Sets input file name. |
|---|
| 109 | Parser(const std::string &filename); |
|---|
| 110 | |
|---|
| 111 | //! Constructor. Uses argc and argv (command line arguments) |
|---|
| 112 | Parser(int argc, char *argv[]); |
|---|
| 113 | |
|---|
| 114 | //! Constructor. Sets input file name and uses argc and argv (command line arguments) |
|---|
| 115 | Parser(const std::string &filename, int argc, char *argv[]); |
|---|
| 116 | |
|---|
| 117 | //! Constructor. Sets and Array of strings |
|---|
| 118 | Parser(const Array<std::string> &setup); |
|---|
| 119 | |
|---|
| 120 | //! Initialization function. Sets input file name. |
|---|
| 121 | void init(const std::string &filename); |
|---|
| 122 | |
|---|
| 123 | //! Initialization function. Uses argc and argv (command line arguments) |
|---|
| 124 | void init(int argc, char *argv[]); |
|---|
| 125 | |
|---|
| 126 | //! Initialization function. Sets input file name and uses argc and argv (command line arguments) |
|---|
| 127 | void init(const std::string &filename, int argc, char *argv[]); |
|---|
| 128 | |
|---|
| 129 | //! Initialization function. Sets and Array of strings |
|---|
| 130 | void init(const Array<std::string> &setup); |
|---|
| 131 | |
|---|
| 132 | //! Sets silent mode if true, or verbose mode if false |
|---|
| 133 | void set_silentmode(bool v=true); |
|---|
| 134 | |
|---|
| 135 | //! Check is \a name exists in the file. Returns \c true if the \a name is found and \c false otherwise. |
|---|
| 136 | bool exist(const std::string &name); |
|---|
| 137 | |
|---|
| 138 | //! Get variable value if \a name can be found (and return true), otherwise keep old value (and return false) |
|---|
| 139 | template<class T> |
|---|
| 140 | bool get(T &var, const std::string &name, int num=-1); |
|---|
| 141 | |
|---|
| 142 | //! Interpret variable \a name as a bool |
|---|
| 143 | bool get_bool(const std::string &name, int num=-1); |
|---|
| 144 | |
|---|
| 145 | //! Interpret variable \a name as an integer |
|---|
| 146 | int get_int(const std::string &name, int num=-1); |
|---|
| 147 | |
|---|
| 148 | //! Interpret variable \a name as a double |
|---|
| 149 | double get_double(const std::string &name, int num=-1); |
|---|
| 150 | |
|---|
| 151 | //! Interpret variable \a name as a string |
|---|
| 152 | std::string get_string(const std::string &name, int num=-1); |
|---|
| 153 | |
|---|
| 154 | //! Interpret variable \a name as a vec |
|---|
| 155 | vec get_vec(const std::string &name, int num=-1); |
|---|
| 156 | |
|---|
| 157 | //! Interpret variable \a name as a ivec |
|---|
| 158 | ivec get_ivec(const std::string &name, int num=-1); |
|---|
| 159 | |
|---|
| 160 | //! Interpret variable \a name as a svec |
|---|
| 161 | svec get_svec(const std::string &name, int num=-1); |
|---|
| 162 | |
|---|
| 163 | //! Interpret variable \a name as a bvec |
|---|
| 164 | bvec get_bvec(const std::string &name, int num=-1); |
|---|
| 165 | |
|---|
| 166 | //! Interpret variable \a name as a mat |
|---|
| 167 | mat get_mat(const std::string &name, int num=-1); |
|---|
| 168 | |
|---|
| 169 | //! Interpret variable \a name as a imat |
|---|
| 170 | imat get_imat(const std::string &name, int num=-1); |
|---|
| 171 | |
|---|
| 172 | //! Interpret variable \a name as a smat |
|---|
| 173 | smat get_smat(const std::string &name, int num=-1); |
|---|
| 174 | |
|---|
| 175 | //! Interpret variable \a name as a bmat |
|---|
| 176 | bmat get_bmat(const std::string &name, int num=-1); |
|---|
| 177 | |
|---|
| 178 | protected: |
|---|
| 179 | |
|---|
| 180 | private: |
|---|
| 181 | |
|---|
| 182 | //! Find the string \c name |
|---|
| 183 | std::string findname(const std::string &name, |
|---|
| 184 | bool &error_flag, |
|---|
| 185 | bool &print_flag, |
|---|
| 186 | int num=0, |
|---|
| 187 | bool keep_brackets=false); |
|---|
| 188 | |
|---|
| 189 | void pre_parsing(void); |
|---|
| 190 | |
|---|
| 191 | Array<std::string> SetupStrings; |
|---|
| 192 | |
|---|
| 193 | bool VERBOSE; |
|---|
| 194 | }; |
|---|
| 195 | |
|---|
| 196 | // ----------------------- Implementation starts here ----------------------- |
|---|
| 197 | |
|---|
| 198 | template<class T> |
|---|
| 199 | bool Parser::get(T &var, const std::string &name, int num) |
|---|
| 200 | { |
|---|
| 201 | bool error_flag, print_flag; |
|---|
| 202 | std::string str = findname(name, error_flag, print_flag, num, true); |
|---|
| 203 | std::istringstream buffer(str); |
|---|
| 204 | if (error_flag) { |
|---|
| 205 | if (VERBOSE) { |
|---|
| 206 | std::cout << name << " = " << var << ";" << std::endl; |
|---|
| 207 | } |
|---|
| 208 | } else { |
|---|
| 209 | buffer >> var; |
|---|
| 210 | if (print_flag) { |
|---|
| 211 | std::cout << name << " = " << var << std::endl; |
|---|
| 212 | } else if (VERBOSE) { |
|---|
| 213 | std::cout << name << " = " << var << ";" << std::endl; |
|---|
| 214 | } |
|---|
| 215 | } |
|---|
| 216 | return !error_flag; |
|---|
| 217 | } |
|---|
| 218 | |
|---|
| 219 | //! Specialization or \c get() for std::string |
|---|
| 220 | template<> |
|---|
| 221 | bool Parser::get(std::string &var, const std::string &name, int num); |
|---|
| 222 | //! Specialization of \c get() for int |
|---|
| 223 | template<> |
|---|
| 224 | bool Parser::get(int &var, const std::string &name, int num); |
|---|
| 225 | //! Specialization of \c get() for bool |
|---|
| 226 | template<> |
|---|
| 227 | bool Parser::get(bool &var, const std::string &name, int num); |
|---|
| 228 | |
|---|
| 229 | } // namespace itpp |
|---|
| 230 | |
|---|
| 231 | #endif // #ifndef PARSER_H |
|---|