#ifndef STIM_ARGUMENTS #define STIM_ARGUMENTS #include #include #include #include #include #include #include /**The arglist class implements command line arguments. Example: 1) Create an arglist instance: stim::arglist args; 2) Add arguments: args.add("help", "prints this help"); args.add("foo", "foo takes a single integer value", "", "[intval]"); args.add("bar", "bar takes two floating point values", "", "[value1], [value2]"); 3) Parse the command line: args.parse(argc, argv); 4) You generally want to immediately test for help and output available arguments: if(args["help"].is_set()) std::cout< desc; //argument values std::vector vals; //integral and numerical flags for each argument std::vector integral; std::vector numerical; //range or example std::string range; //flag is true when the argument is user-specified bool flag; bool char_numerical(char c){ if( (c >= '0' && c <= '9') || c == '-' || c == '.') return true; return false; } bool char_integral(char c){ if( (c >= '0' && c <= '9') || c == '-') return true; return false; } /// Test if a given string contains a numerical (real) value bool test_numerical(std::string v){ for(size_t i = 0; i < v.length(); i++){ //for each character in the string if(!char_numerical(v[i])) return false; } return true; } /// Test if a given string contains an integer value bool test_integral(std::string v){ for(size_t i = 0; i < v.length(); i++){ //for each character in the string if(!char_integral(v[i])) return false; } return true; } void parse_val(const std::string &s){ vals.clear(); std::stringstream ss(s); std::string item; while (std::getline(ss, item, ' ')) { vals.push_back(item); } } void parse_desc(const std::string &s){ desc.clear(); std::stringstream ss(s); std::string item; while (std::getline(ss, item, '\n')) { desc.push_back(item); } } public: void set_ansi(bool b){ ansi = b; } //create an option with a given name, description, and default value cmd_option(std::string _name, std::string _desc, std::string _default = "", std::string _range = "") { name = _name; parse_desc(_desc); parse_val(_default); //if a default value is provided, set the flag if(_default != "") flag = true; else flag = false; range = _range; } size_t nargs() { return vals.size(); } //return the value of a text option std::string as_string(size_t n = 0) { if(!flag) { std::cout<<"ERROR - Option requested without being set: "< n) return vals[n]; else return ""; } //return the value of a floating point option double as_float(size_t n = 0) { if(!flag) { std::cout<<"ERROR - option requested without being set: "< n) { float r; if ( ! (std::istringstream(vals[n]) >> r) ) r = 0; return r; } else return 0; } //return the value of an integer option int as_int(size_t n = 0) { if(!flag) { std::cout<<"ERROR - option requested without being set: "< n) { int r; if ( ! (std::istringstream(vals[n]) >> r) ) r = 0; return r; } else return 0; } //returns true if the specified argument can be represented as a number bool is_num(size_t n = 0){ bool decimal = false; for(size_t i = 0; i < vals[n].size(); i++){ if(vals[n][i] == '-' && i != 0) return false; else if(vals[n][i] == '.'){ if(decimal) return false; else decimal = true; } else if(vals[n][i] < '0') return false; else if(vals[n][i] > '9') return false; } return true; } //get the width of the left column size_t col_width() { size_t n = 3; //add the length of the option name n += name.size(); //if there are any default parameters if(vals.size() > 0) { //padding (parenthesis, =, etc.) n += 6; //for each default option value for(size_t v=0; v opts; std::vector args; //column width of the longest option size_t col_width; //list of sections std::vector sections; public: arglist(){ col_width = 0; ansi = true; //set ansi to false by default if this is a Windows system // (console doesn't support ANSI colors) #ifdef _WIN32 ansi=false; #endif } ///Sets ANSI support (default is on), which allows colored values in the help output. /// @param b is a boolean value specifying ANSI support (true is on, false is off) void set_ansi(bool b) { ansi = b; for(unsigned int i=0; i(col_width, opt.col_width()); } ///Specifies a section name that can be used to organize parameters in the output. /// @param _name is the name of the section, which will be displayed to the user void section(std::string _name) { argsection s; s.name = _name; s.index = opts.size(); sections.push_back(s); } ///Outputs supported arguments. If ANSI support is available, they will be color-coded. Generally this is called in response to "--help" std::string str() { std::stringstream ss; int si = -1; if(sections.size() > 0) si = 0; //for each option for(unsigned int a=0; a= opts.size()){ std::cout<<"ERROR stim::arglist: option name '"<<_name<<"' not found"<::iterator it; it = std::find(opts.begin(), opts.end(), _name);// - opts.begin(); if(it == opts.end()){ std::cout<<"ERROR - Unspecified parameter name: "<<_name<is_set(); } ///Returns the number of parameters for a specified argument /// @param _name is the name of the argument whose parameter number will be returned size_t nargs(std::string _name){ std::vector::iterator it; it = find(opts.begin(), opts.end(), _name);// - opts.begin(); if(it == opts.end()){ std::cout<<"ERROR - Unspecified parameter name: "<<_name<nargs(); } ///Returns the number of arguments that have been set size_t nargs(){ return args.size(); } /// Returns the number of options that are set size_t nopts(){ size_t n = 0; //initialize the counter for the number of options for(size_t i = 0; i < opts.size(); i++) //go through each option if(opts[i].is_set()) n++; //if a value is specified, increment the counter return n; } ///Returns the name of an argument, given its index /// @param a is the index of the requested argument std::string arg(size_t a){ return args[a]; } /// Returns an std::vector of argument strings std::vector arg_vector(){ return args; } ///Returns an object describing the argument /// @param _name is the name of the requested argument cmd_option operator[](std::string _name){ std::vector::iterator it; it = find(opts.begin(), opts.end(), _name);// - opts.begin(); if(it == opts.end()){ std::cout<<"ERROR - Unspecified parameter name: "<<_name<