[complement-svn] SF.net SVN: complement: [1876] trunk/complement/explore
Status: Pre-Alpha
Brought to you by:
complement
From: <Dmi...@us...> - 2008-05-15 15:23:21
|
Revision: 1876 http://complement.svn.sourceforge.net/complement/?rev=1876&view=rev Author: DmitryOsmakov Date: 2008-05-15 08:22:47 -0700 (Thu, 15 May 2008) Log Message: ----------- fixed lib Opts : default values are enabled (by cost of some overhead in runtime and different usage of function get) , error handling updated (more standart way) , function to get access to all arguments of specified option is added Modified Paths: -------------- trunk/complement/explore/include/misc/opts.h trunk/complement/explore/lib/misc/opts.cpp trunk/complement/explore/lib/misc/ut/misc_test_suite.cc trunk/complement/explore/lib/misc/ut/opts_test.cc trunk/complement/explore/lib/misc/ut/opts_test.h Modified: trunk/complement/explore/include/misc/opts.h =================================================================== --- trunk/complement/explore/include/misc/opts.h 2008-05-15 08:35:35 UTC (rev 1875) +++ trunk/complement/explore/include/misc/opts.h 2008-05-15 15:22:47 UTC (rev 1876) @@ -9,6 +9,8 @@ #include <sstream> #include <typeinfo> #include <cctype> +#include <exception> +#include <stdexcept> class Opt { @@ -18,6 +20,7 @@ std::string longname; std::string desc; std::vector< std::string > args; + std::string v; bool has_arg; bool is_set; @@ -33,16 +36,21 @@ copyright(_copyright) { } - // adding option - void add( char _shortname, const std::string& _longname = "", const std::string& _desc = "", bool has_arg = false ); + // adding option / flag + template <class T> + void add( char _shortname,T default_value,const std::string& _longname = "", const std::string& _desc = "" ); + void addflag( char _shortname,const std::string& _longname = "",const std::string& _desc = "" ); // getting option template <class T> - T get( char _shortname, T& dest ); + T get( char _shortname ); template <class T> - T get( const std::string& _longname, T& dest ); + T get( const std::string& _longname ); + template <class BackInsertIterator> + void getemall(char _shortname,BackInsertIterator bi); + bool is_set( char _shortname ); bool is_set( const std::string& _longname ); @@ -60,34 +68,33 @@ std::string get_copyright() const; // error handling - struct invalid_opt + struct invalid_opt : public std::logic_error { - std::string optname; - invalid_opt(const std::string& _optname) : - optname(_optname) + std::logic_error(std::string("invalid opt: ").append(_optname)) { } }; - - struct missing_arg + + struct missing_arg : public std::logic_error { - std::string optname; - missing_arg( const std::string& _optname) : - optname(_optname) + std::logic_error(std::string("missing argument for option ").append(_optname)) { } }; - struct invalid_arg + struct invalid_arg : public std::logic_error { - std::string optname; - std::string argname; - invalid_arg( const std::string& _optname, const std::string& _argname) : - optname(_optname), - argname(_argname) + std::logic_error(std::string("invalid argument [").append(_argname).append("] for option ").append(_optname)) { } }; + + struct bad_usage : public std::runtime_error + { + bad_usage( const std::string& what) : + std::runtime_error(what) + { } + }; //std::vector< std::string > args; @@ -108,58 +115,117 @@ }; template <class T> -T Opts::get( char _shortname, T& res ) +void Opts::add(char _shortname,T _default_value,const std::string& _longname,const std::string& _desc) { + addflag(_shortname,_longname,_desc); + std::stringstream ss; + ss << _default_value; + storage[storage.size() - 1].v = ss.str(); + storage[storage.size() - 1].has_arg = true; +} + +template <class T> +T Opts::get( char _shortname ) +{ int i; - for (i = 0;i < storage.size();i++) { + T res; + for (i = 0;i < storage.size();i++) if (storage[i].shortname == _shortname) { - if (storage[i].is_set && storage[i].has_arg) - if (!storage[i].args.empty()) - { - try - { - std::stringstream ss(storage[i].args[0]); - ss >> res; - } - catch(...) - { - throw invalid_arg(std::string("-") + std::string(1,_shortname),storage[i].args[0]); - } - } + if (!storage[i].has_arg) + throw bad_usage("using Opts::get for option without arguments"); + + if (!storage[i].args.empty()) + storage[i].v = storage[i].args[0]; + + try + { + std::stringstream ss(storage[i].v); + ss >> res; + } + catch(...) + { + throw invalid_arg(std::string("-") + std::string(1,_shortname),storage[i].v); + } + break; } - } + if (i == storage.size()) throw invalid_opt(std::string("-") + std::string(1,_shortname)); return res; } + + template <class T> -T Opts::get(const std::string& _longname,T& res) +T Opts::get( const std::string& _longname ) { int i; + T res; for (i = 0;i < storage.size();i++) if (storage[i].longname == _longname) { - if (storage[i].is_set && storage[i].has_arg) - if (!storage[i].args.empty()) + if (!storage[i].has_arg) + throw bad_usage("using Opts::get for option without arguments"); + + if (!storage[i].args.empty()) + storage[i].v = storage[i].args[0]; + + try + { + std::stringstream ss(storage[i].v); + ss >> res; + } + catch(...) + { + throw invalid_arg(std::string("--") + _longname,storage[i].v); + } + + break; + } + + if (i == storage.size()) + throw invalid_opt(std::string("--") + _longname); + return res; +} + +template <class BackInsertIterator> +void Opts::getemall( char _shortname , BackInsertIterator bi) +{ + int i; + for (i = 0;i < storage.size();i++) + if (storage[i].shortname == _shortname) + { + if (!storage[i].has_arg) + throw bad_usage("using Opts::getemall for option without arguments"); + + if (!storage[i].v.empty()) + { + std::stringstream ss(storage[i].v); + ss >> *bi++; + } + + if (!storage[i].args.empty()) + for (int j = 0;j < storage[i].args.size();j++) { try { - std::stringstream ss(storage[i].args[0]); - ss >> res; + std::stringstream ss(storage[i].args[j]); + ss >> *bi++; } catch(...) { - throw invalid_arg(_longname,storage[i].args[0]); + throw invalid_arg(std::string("-") + std::string(1,_shortname),storage[i].v); } } + break; - } + } + if (i == storage.size()) - throw invalid_opt(_longname); - return res; + throw invalid_opt(std::string("-") + std::string(1,_shortname)); } + #endif Modified: trunk/complement/explore/lib/misc/opts.cpp =================================================================== --- trunk/complement/explore/lib/misc/opts.cpp 2008-05-15 08:35:35 UTC (rev 1875) +++ trunk/complement/explore/lib/misc/opts.cpp 2008-05-15 15:22:47 UTC (rev 1876) @@ -95,16 +95,16 @@ out << pname << " [option ...] [optiongoup ...] [end operands ...]" << endl; out << "available options:" << endl; for (int i = 0;i < storage.size();i++) - out << "-" << storage[i].shortname << "\t[--" << storage[i].longname << "]\t-\t" << storage[i].desc << endl; + out << "-" << storage[i].shortname << "\t[--" << storage[i].longname << "] [" << storage[i].v << "]\t-\t" << storage[i].desc << endl; } -void Opts::add(char _shortname,const string& _longname,const string& _desc,bool has_arg ) +void Opts::addflag(char _shortname,const string& _longname,const string& _desc) { Opt opt; opt.shortname = _shortname; opt.longname = _longname; opt.desc = _desc; - opt.has_arg = has_arg; + opt.has_arg = false; opt.is_set = false; storage.push_back(opt); } Modified: trunk/complement/explore/lib/misc/ut/misc_test_suite.cc =================================================================== --- trunk/complement/explore/lib/misc/ut/misc_test_suite.cc 2008-05-15 08:35:35 UTC (rev 1875) +++ trunk/complement/explore/lib/misc/ut/misc_test_suite.cc 2008-05-15 15:22:47 UTC (rev 1876) @@ -66,9 +66,12 @@ t.add( &opts_test::int_option_long, opts, "option with int parameter, long", t.add( &opts_test::int_option, opts, "option with int parameter" ) ); + t.add( &opts_test::defaults, opts, "defaults" ); + + t.add( &opts_test::bad_option, opts, "bad option" ); t.add( &opts_test::bad_argument, opts, "bad argument" ); - + t.add( &opts_test::user_defined, opts, "user-defined type" ); t.add( &opts_test::compound, opts, "compound" ); @@ -78,8 +81,11 @@ t.add( &opts_test::args, opts,"args"); t.add( &opts_test::stop, opts,"stop"); + + // check whether autocomplement works + t.add( &opts_test::autocomplement, opts,"autocomplement"); - t.add( &opts_test::reduction, opts,"reduction"); + t.add( &opts_test::multiple_args, opts,"multiple_args"); return t.girdle(); }; Modified: trunk/complement/explore/lib/misc/ut/opts_test.cc =================================================================== --- trunk/complement/explore/lib/misc/ut/opts_test.cc 2008-05-15 08:35:35 UTC (rev 1875) +++ trunk/complement/explore/lib/misc/ut/opts_test.cc 2008-05-15 15:22:47 UTC (rev 1876) @@ -11,6 +11,8 @@ #include "opts_test.h" #include <misc/opts.h> +#include <set> +#include <vector> // #include <iostream> @@ -23,7 +25,7 @@ Opts opts; - opts.add( 'h', "help", "print this help message" ); + opts.addflag( 'h', "help", "print this help message" ); try { opts.parse( argc, argv ); @@ -45,7 +47,7 @@ Opts opts; - opts.add( 'h', "help", "print this help message" ); + opts.addflag( 'h', "help", "print this help message" ); try { opts.parse( argc, argv ); @@ -68,15 +70,13 @@ Opts opts; - opts.add( 'p', "port", "listen tcp port" , true); + opts.add( 'p', 0,"port", "listen tcp port"); try { opts.parse( argc, argv ); - int port = 0; - EXAM_CHECK( opts.is_set( 'p' ) ); - EXAM_CHECK( opts.get( 'p', port ) == 80 ); + EXAM_CHECK( opts.get<int>( 'p' ) == 80 ); } catch ( const Opts::invalid_opt& e ) { } @@ -93,15 +93,14 @@ Opts opts; - opts.add( 'p', "port", "listen tcp port" , true ); + opts.add( 'p', 0, "port", "listen tcp port"); try { opts.parse( argc, argv ); - int port = 0; EXAM_CHECK( opts.is_set( 'p' ) ); - EXAM_CHECK( opts.get( 'p', port ) == 80 ); + EXAM_CHECK( opts.get<int>( 'p' ) == 80 ); } catch ( const Opts::invalid_opt& e ) { } @@ -111,6 +110,30 @@ return EXAM_RESULT; } +int EXAM_IMPL(opts_test::defaults) +{ + const char* argv[] = { "name" }; + int argc = sizeof( argv ) / sizeof(argv[0]); + + Opts opts; + + opts.add( 'p', 0, "port", "listen tcp port"); + + try { + opts.parse( argc, argv ); + + + EXAM_CHECK( !opts.is_set( 'p' ) ); + EXAM_CHECK( opts.get<int>( 'p' ) == 0 ); + } + catch ( const Opts::invalid_opt& e ) { + } + catch ( const Opts::invalid_arg& e ) { + } + + return EXAM_RESULT; +} + int EXAM_IMPL(opts_test::bad_option) { const char* argv[] = { "name", "-v" }; @@ -118,7 +141,7 @@ Opts opts; - opts.add( 'h', "help", "print this help message" ); + opts.addflag( 'h', "help", "print this help message" ); bool exception_happens = false; @@ -129,7 +152,6 @@ } catch ( const Opts::invalid_opt& e ) { exception_happens = true; - EXAM_CHECK( e.optname == "-v" ); } catch ( const Opts::invalid_arg& e ) { } @@ -150,17 +172,15 @@ bool exception_happens = false; - try { - opts.parse( argc, argv ); - - EXAM_ERROR( "exception expected" ); + opts.parse( argc, argv ); + + try + { + int t = opts.get<int>('p'); } - catch ( const Opts::invalid_opt& e ) { - } - catch ( const Opts::invalid_arg& e ) { + catch(const Opts::invalid_arg& e) + { exception_happens = true; - EXAM_CHECK( e.optname == "--port" ); - EXAM_CHECK( e.argname == "www" ); } EXAM_CHECK( exception_happens ); @@ -176,7 +196,7 @@ Opts opts; - opts.add( 'v', "verbose", "more trace messages" ); + opts.addflag( 'v', "verbose", "more trace messages" ); opts.parse( argc, argv ); @@ -189,7 +209,7 @@ Opts opts; - opts.add( 'v', "verbose", "more trace messages" ); + opts.addflag( 'v', "verbose", "more trace messages" ); opts.parse( argc, argv ); @@ -202,7 +222,7 @@ Opts opts; - opts.add( 'v', "verbose", "more trace messages" ); + opts.addflag( 'v', "verbose", "more trace messages" ); opts.parse( argc, argv ); @@ -220,9 +240,9 @@ Opts opts; - opts.add( 'a', "a-option", "option a" ); - opts.add( 'b', "b-option", "option b" ); - opts.add( 'c', "c-option", "option c" ); + opts.addflag( 'a', "a-option", "option a" ); + opts.addflag( 'b', "b-option", "option b" ); + opts.addflag( 'c', "c-option", "option c" ); opts.parse( argc, argv ); @@ -241,7 +261,7 @@ Opts opts; - opts.add( 'f', "config", "configuration file",true ); + opts.add( 'f',string("default.conf"), "config", "configuration file"); opts.parse( argc, argv ); @@ -257,7 +277,7 @@ Opts opts; - opts.add( 'f', "config", "configuration file",true ); + opts.add( 'f', string("default.conf"), "config", "configuration file" ); opts.parse( argc, argv ); @@ -273,7 +293,7 @@ Opts opts; - opts.add( 'f', "config", "configuration file",true ); + opts.add( 'f', string("default.conf"), "config", "configuration file" ); opts.parse( argc, argv ); @@ -294,7 +314,7 @@ Opts opts; - opts.add( 'a', "a-option", "option a" ); + opts.addflag( 'a', "a-option", "option a" ); opts.parse( argc, argv ); @@ -338,21 +358,20 @@ Opts opts; - opts.add( 's', "start-point", "start point", true ); + opts.add( 's', point(1,1) ,"start-point", "start point"); opts.parse( argc, argv ); - point p( 1, 1 ); + point p = opts.get<point>( 's' ); - opts.get( 's', p ); - - EXAM_CHECK( (p.x == 1) && (p.y = 2) ); + EXAM_CHECK( (p.x == 1) && (p.y == 2) ); } return EXAM_RESULT; } -int EXAM_IMPL(opts_test::reduction) +// check whether autocomplement works +int EXAM_IMPL(opts_test::autocomplement) { { const char* argv[] = { "name" , "--num" , "4"}; @@ -360,14 +379,37 @@ Opts opts; - opts.add('n',"number_of_processors","number of processors",true ); + opts.add('n',1,"number_of_processors","number of processors" ); opts.parse( argc, argv ); - int n; - opts.get('n',n); - EXAM_CHECK( n == 4 ); + EXAM_CHECK( opts.get<int>('n') == 4 ); } return EXAM_RESULT; } + +int EXAM_IMPL(opts_test::multiple_args) +{ + { + const char* argv[] = { "name" , "-I" , "first","-I","second","-I","third"}; + int argc = sizeof( argv ) / sizeof(argv[0]); + + Opts opts; + + opts.add('I',"/usr/include","include","include paths" ); + + opts.parse( argc, argv ); + + vector<string> vs(10); + + opts.getemall('I',vs.begin()); + + EXAM_CHECK( vs[0] == "/usr/include" ); + EXAM_CHECK( vs[1] == "first" ); + EXAM_CHECK( vs[2] == "second" ); + EXAM_CHECK( vs[3] == "third" ); + } + + return EXAM_RESULT; +} Modified: trunk/complement/explore/lib/misc/ut/opts_test.h =================================================================== --- trunk/complement/explore/lib/misc/ut/opts_test.h 2008-05-15 08:35:35 UTC (rev 1875) +++ trunk/complement/explore/lib/misc/ut/opts_test.h 2008-05-15 15:22:47 UTC (rev 1876) @@ -23,6 +23,7 @@ int EXAM_DECL(bool_option_long); int EXAM_DECL(int_option); int EXAM_DECL(int_option_long); + int EXAM_DECL(defaults); int EXAM_DECL(bad_option); int EXAM_DECL(bad_argument); int EXAM_DECL(multiple); @@ -30,7 +31,8 @@ int EXAM_DECL(args); int EXAM_DECL(stop); int EXAM_DECL(user_defined); - int EXAM_DECL(reduction); + int EXAM_DECL(autocomplement); + int EXAM_DECL(multiple_args); }; #endif // __MISC_TEST_H This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |