/*---------------------------------------------------------------------------* * IT++ * *---------------------------------------------------------------------------* * Copyright (c) 1995-2001 by Tony Ottosson, Thomas Eriksson, Pål Frenger, * * Tobias Ringström, and Jonas Samuelsson. * * * * Permission to use, copy, modify, and distribute this software and its * * documentation under the terms of the GNU General Public License is hereby * * granted. No representations are made about the suitability of this * * software for any purpose. It is provided "as is" without expressed or * * implied warranty. See the GNU General Public License for more details. * *---------------------------------------------------------------------------*/ /*! \file \brief Definition of an argument parser class \author Thomas Eriksson and Pål Frenger (Thanks to Svante signell for valuable input) 1.18 2004/10/06 00:17:53 */ #ifndef __parser_h #define __parser_h #define MAX_STR_LEN 4096 #include "base/vec.h" #include "base/mat.h" #include "base/array.h" #include #include namespace itpp { /*! \defgroup parser Argument parser */ /*! \ingroup parser \brief Argument Parser Class \author Thomas Eriksson and Pål Frenger (Thanks to Svante Signell for valuable input) This class parses strings to variables. The syntax is compatible with Matlab and Octave. It can be used in several different ways. The following test program and test data file gives 5 examples: The test program looks as follows: \include parser_test.cpp The data file \c parser_test_data.txt looks as follows: \include parser_test_data.txt Beside the type-specific get methods, like get_int(), there is a templated get method called get(), that can handle all variable types that have an istream operator defined, e.g. Arrays. The get() method takes the variable value as an input/output parameter. If the variable name cannot be found, the old value is kept. Here is an example: \code // Declare and initialize a variable Array var("{[1] [2 3] [4 5 6]}"); // Let the Parser p get the variable named my_var_name bool my_var_name_was_found = p.get(var, "my_var_name"); \endcode In the above example, if \c my_var_name was not found, \c var keeps its old value {[1] [2 3] [4 5 6]}. In non-silent mode, the get() method echoes the variable values to the standard output in Matlab/Octave m-file style. */ class Parser { public: //! Default Constructor Parser(); //! Constructor. Sets input file name. Parser(const std::string &filename); //! Constructor. Uses argc and argv (command line arguments) Parser(int argc, char *argv[]); //! Constructor. Sets input file name and uses argc and argv (command line arguments) Parser(const std::string &filename, int argc, char *argv[]); //! Constructor. Sets and Array of strings Parser(const Array &setup); //! Initialization function. Sets input file name. void init(const std::string &filename); //! Initialization function. Uses argc and argv (command line arguments) void init(int argc, char *argv[]); //! Initialization function. Sets input file name and uses argc and argv (command line arguments) void init(const std::string &filename, int argc, char *argv[]); //! Initialization function. Sets and Array of strings void init(const Array &setup); //! Sets silent mode if true, or verbose mode if false void set_silentmode(bool v=true); //! Check is \a name exists in the file. Returns \c true if the \a name is found and \c false otherwise. bool exist(const std::string &name); //! Get variable value if \a name can be found (and return true), otherwise keep old value (and return false) template bool get(T &var, const std::string &name, int num=-1); //! Interpret variable \a name as a bool bool get_bool(const std::string &name, int num=-1); //! Interpret variable \a name as an integer int get_int(const std::string &name, int num=-1); //! Interpret variable \a name as a double double get_double(const std::string &name, int num=-1); //! Interpret variable \a name as a string std::string get_string(const std::string &name, int num=-1); //! Interpret variable \a name as a vec vec get_vec(const std::string &name, int num=-1); //! Interpret variable \a name as a ivec ivec get_ivec(const std::string &name, int num=-1); //! Interpret variable \a name as a svec svec get_svec(const std::string &name, int num=-1); //! Interpret variable \a name as a bvec bvec get_bvec(const std::string &name, int num=-1); //! Interpret variable \a name as a mat mat get_mat(const std::string &name, int num=-1); //! Interpret variable \a name as a imat imat get_imat(const std::string &name, int num=-1); //! Interpret variable \a name as a smat smat get_smat(const std::string &name, int num=-1); //! Interpret variable \a name as a bmat bmat get_bmat(const std::string &name, int num=-1); protected: private: //! Find the string \c name std::string findname(const std::string &name, bool &error_flag, bool &print_flag, int num=0, bool keep_brackets=false); void pre_parsing(void); Array SetupStrings; bool VERBOSE; }; // ----------------------- Implementation starts here ----------------------- template bool Parser::get(T &var, const std::string &name, int num) { bool error_flag, print_flag; string str = findname(name, error_flag, print_flag, num, true); std::istringstream buffer(str); if (error_flag) { if (VERBOSE) { cout << name << " = " << var << ";" << endl; } } else { buffer >> var; if (print_flag) { cout << name << " = " << var << endl; } else if (VERBOSE) { cout << name << " = " << var << ";" << endl; } } return !error_flag; } // Specialization for std::string template<> bool Parser::get(std::string &var, const std::string &name, int num); } //namespace itpp #endif //__parser_h