[complement-svn] SF.net SVN: complement: [1928] trunk/complement/explore
Status: Pre-Alpha
Brought to you by:
complement
From: <com...@us...> - 2008-06-29 21:48:36
|
Revision: 1928 http://complement.svn.sourceforge.net/complement/?rev=1928&view=rev Author: complement Date: 2008-06-29 14:48:33 -0700 (Sun, 29 Jun 2008) Log Message: ----------- revision of options framework. insert object with type and type check into option; default value passed via [] operator; option registration done via << oprator. Modified Paths: -------------- trunk/complement/explore/include/misc/opts.h trunk/complement/explore/lib/exam/ut/exam_self_test.cc trunk/complement/explore/lib/misc/ChangeLog trunk/complement/explore/lib/misc/Makefile.inc trunk/complement/explore/lib/misc/opts.cc trunk/complement/explore/lib/misc/ut/Makefile trunk/complement/explore/lib/misc/ut/Makefile.inc trunk/complement/explore/lib/misc/ut/misc_test_suite.cc trunk/complement/explore/lib/misc/ut/opts_test.cc Modified: trunk/complement/explore/include/misc/opts.h =================================================================== --- trunk/complement/explore/include/misc/opts.h 2008-06-29 21:48:10 UTC (rev 1927) +++ trunk/complement/explore/include/misc/opts.h 2008-06-29 21:48:33 UTC (rev 1928) @@ -1,10 +1,10 @@ -// -*- C++ -*- Time-stamp: <08/06/29 13:52:41 ptr> +// -*- C++ -*- Time-stamp: <08/06/29 22:16:12 ptr> /* * Copyright (c) 2008 * Dmitry Osmakov * - * Copyright (c) 2008 + * Copyright (c) 1997-1998, 2001, 2008 * Petr Ovtchenkov * * Licensed under the Academic Free License Version 3.0 @@ -17,11 +17,15 @@ #include <iostream> #include <string> #include <vector> +#include <list> #include <sstream> #include <typeinfo> #include <cctype> #include <exception> #include <stdexcept> +#include <algorithm> +#include <functional> +#include <iterator> class option_base { @@ -31,6 +35,7 @@ shortname( _short_var ), longname( _long_var ), desc( _description ), + token( _count++ ), has_arg( false ) { } @@ -38,6 +43,7 @@ shortname( _short_var ), longname(), desc( _description ), + token( _count++ ), has_arg( false ) { } @@ -45,11 +51,12 @@ shortname( 0 ), longname( _long_var ), desc( _description ), + token( _count++ ), has_arg( false ) { } - option_base& operator []( const std::string& d ) - { default_v = d; has_arg = true; } + virtual ~option_base() + { } bool operator ==( const std::string& _longname ) const { return longname == _longname; } @@ -58,31 +65,300 @@ bool operator ==( int _token ) const { return token == _token; } - private: + virtual const std::type_info& type() const = 0; + + template <class T> + bool assign( T& v ) const + { + if ( this->type() != typeid(T) ) { + throw std::invalid_argument( "types mismatch" ); + } + return _assign( static_cast<void*>(&v) ); + } + + protected: + virtual void read( const char* str ) = 0; + virtual void read( const std::string& str ) = 0; + virtual bool _assign( void* ) const = 0; + virtual std::ostream& _describe( std::ostream& ) const = 0; + char shortname; std::string longname; std::string desc; - std::string default_v; int token; - - std::vector< std::string > args; - std::vector< int > pos; + protected: + std::vector<int> pos; + bool has_arg; - friend std::ostream& operator <<( std::ostream& t, const option_base& opt ); + // friend std::ostream& operator <<( std::ostream& t, const option_base& opt ); friend class Opts; + + private: + static int _count; }; +namespace detail { + +template <class P, class V> +class deref_equal : + public std::binary_function<P,V,bool> +{ + public: + bool operator()(const P& __x, const V& __y) const + { return *__x == __y; } +}; + +} // namespace detail + +template <class T> +class option : + public option_base +{ + public: + option( const char* _description, char _short_var, const char* _long_var ) : + option_base( _description, _short_var, _long_var ) + { } + + option( const char* _description, char _short_var ) : + option_base( _description, _short_var ) + { } + + option( const char* _description, const char* _long_var ) : + option_base( _description, _long_var ) + { } + + virtual const std::type_info& type() const + { return typeid( T ); } + + option<T>& operator []( const T& val ) + { args.push_back( val ); has_arg = true; return *this; } + + template <class BackInstertIterator> + void get( BackInstertIterator bi ) const + { std::copy( args.begin(), args.end(), bi ); } + + protected: + virtual std::ostream& _describe( std::ostream& o ) const; + + virtual bool _assign( void* v ) const + { + if ( args.empty() ) { + // throw + } + *reinterpret_cast<T*>(v) = args.front(); + + return !pos.empty(); + } + + private: + std::list<T> args; + + void read( const char *str ) throw (std::invalid_argument) + { + std::istringstream s( str ); + T _v; + if ( !(s >> _v).fail() ) { + if ( has_arg && args.size() == 1 && pos.size() == 0 ) { // override default value + args.front() = _v; + } else { + args.push_back( _v ); + } + } else { + throw std::invalid_argument( str ); + } + } + + void read( const std::string& str ) throw (std::invalid_argument) + { + std::istringstream s( str ); + T _v; + if ( !(s >> _v).fail() ) { + if ( has_arg && args.size() == 1 && pos.size() == 0 ) { // override default value + args.front() = _v; + } else { + args.push_back( _v ); + } + } else { + throw std::invalid_argument( str ); + } + } + + friend class Opts; +}; + +template <class T> +std::ostream& option<T>::_describe( std::ostream& out ) const +{ + if ( option_base::shortname != 0 ) { + out << '-' << option_base::shortname; + if ( option_base::has_arg ) { + out << " <" << typeid(T).name() << ">"; + } + if ( !option_base::longname.empty() ) { + out << ", "; + } + } + + if ( !option_base::longname.empty() ) { + out << "--" << option_base::longname; + if ( option_base::has_arg ) { + out << "=<" << typeid(T).name() << ">"; + } + } + + if ( option_base::has_arg ) { + out << " [" << args.front() << "]\t"; + } else { + out << '\t'; + } + + return out << option_base::desc; +} + +template <> +class option<std::string> : + public option_base +{ + public: + option( const char* _description, char _short_var, const char* _long_var ) : + option_base( _description, _short_var, _long_var ) + { } + + option( const char* _description, char _short_var ) : + option_base( _description, _short_var ) + { } + + option( const char* _description, const char* _long_var ) : + option_base( _description, _long_var ) + { } + + virtual const std::type_info& type() const + { return typeid( std::string ); } + + option<std::string>& operator []( const char* val ) + { args.push_back( std::string(val) ); has_arg = true; return *this; } + + option<std::string>& operator []( const std::string& val ) + { args.push_back( val ); has_arg = true; return *this; } + + template <class BackInstertIterator> + void get( BackInstertIterator bi ) const + { std::copy( args.begin(), args.end(), bi ); } + + protected: + virtual std::ostream& _describe( std::ostream& o ) const; + + virtual bool _assign( void* v ) const + { + if ( args.empty() ) { + // throw + } + *reinterpret_cast<std::string*>(v) = args.front(); + + return !pos.empty(); + } + + private: + std::list<std::string> args; + + void read( const char *str ) + { + if ( has_arg && args.size() == 1 && pos.size() == 0 ) { // override default value + args.front() = str; + } else { + args.push_back( std::string( str ) ); + } + } + + void read( const std::string& str ) + { + if ( has_arg && args.size() == 1 && pos.size() == 0 ) { // override default value + args.front() = str; + } else { + args.push_back( str ); + } + } + + friend class Opts; +}; + +template <> +class option<char*> : + public option_base +{ + public: + option( const char* _description, char _short_var, const char* _long_var ) : + option_base( _description, _short_var, _long_var ) + { } + + option( const char* _description, char _short_var ) : + option_base( _description, _short_var ) + { } + + option( const char* _description, const char* _long_var ) : + option_base( _description, _long_var ) + { } + + virtual const std::type_info& type() const + { return typeid( std::string ); } + + option<char*>& operator []( const char* val ) + { args.push_back( std::string(val) ); has_arg = true; return *this; } + + option<char*>& operator []( const std::string& val ) + { args.push_back( val ); has_arg = true; return *this; } + + template <class BackInstertIterator> + void get( BackInstertIterator bi ) const + { std::copy( args.begin(), args.end(), bi ); } + + protected: + virtual std::ostream& _describe( std::ostream& o ) const; + + virtual bool _assign( void* v ) const + { + if ( args.empty() ) { + // throw + } + *reinterpret_cast<std::string*>(v) = args.front(); + + return !pos.empty(); + } + + private: + std::list<std::string> args; + + void read( const char *str ) + { + if ( has_arg && args.size() == 1 && pos.size() == 0 ) { // override default value + args.front() = str; + } else { + args.push_back( std::string( str ) ); + } + } + + void read( const std::string& str ) + { + if ( has_arg && args.size() == 1 && pos.size() == 0 ) { // override default value + args.front() = str; + } else { + args.push_back( str ); + } + } + + friend class Opts; +}; + class Opts { private: - typedef std::vector< option_base > options_container_type; - options_container_type storage; + typedef std::vector< option_base* > options_container_type; + options_container_type storage; public: - Opts() : - free_token(0) + Opts() { } void description( const char* text ) @@ -97,46 +373,51 @@ void copyright( const char* text ) { _copyright = text; } - // adding option / flag (option that doesn't need arguments) - template <class T> - int add( const std::string& _longname,T _default_value,const std::string& _desc = "(no decription)" ); template <class T> - int add( char _shortname,T _default_value,const std::string& _longname = "(no longname)", const std::string& _desc = "(no decription)" ); + Opts& operator << ( const option<T>& o ) + { + storage.push_back( new option<T>( o ) ); + return *this; + } - int addflag( const std::string& _longname = "(no longname)",const std::string& desc = "(no decription)"); - - int addflag( char _shortname,const std::string& _longname = "(no longname)",const std::string& _desc = "(no decription)" ); - // getting option - template < class T ,class V > - T get( V field ); - - - template < class V > - std::string get( V field ); - + template <class T ,class V> + T get( const V& field, const T& ); - template <class T , class V> - T get_default( V field ); + template <class T, class V> + T get( const V& field ); - template < class V > - std::string get_default( V field ); + template <class BackInsertIterator> + void getemall( char field , BackInsertIterator bi ); + template <class BackInsertIterator> + void getemall( const std::string& field , BackInsertIterator bi ); + template <class BackInsertIterator> + void getemall( int field , BackInsertIterator bi ); - template < class V , class BackInsertIterator> - void getemall( V field , BackInsertIterator bi); + bool is_set( char field ) const; + bool is_set( const char* field ) const + { return is_set( std::string(field) ); } + bool is_set( const std::string& field ) const; + bool is_set( int field ) const; + int get_cnt( char field ) const; + int get_cnt( const char* field ) const + { return get_cnt( std::string(field) ); } + int get_cnt( const std::string& field ) const; + int get_cnt( int field ) const; - template < class T > - bool is_set( T field ) const; + template <class BackInsertIterator> + void get_pos( char, BackInsertIterator bi); + template <class BackInsertIterator> + void get_pos( const char* f, BackInsertIterator bi) + { get_pos( std::string(f), bi ); } + template <class BackInsertIterator> + void get_pos( const std::string&, BackInsertIterator bi); + template <class BackInsertIterator> + void get_pos( int, BackInsertIterator bi); - template < class T > - int get_cnt( T field ) const; - - template < class V , class BackInsertIterator > - void get_pos( V field , BackInsertIterator bi); - // parse void parse(int& ac, const char** av); @@ -169,9 +450,10 @@ { } }; + int last_token() const + { return storage.empty() ? -1 : storage.back()->token; } + private: - int free_token; - std::string pname; std::string _brief; std::string _usage; @@ -182,65 +464,39 @@ bool is_opt_name( const std::string& s ); bool is_flag_group( const std::string& s ); bool is_substr(const std::string& small, const std::string& big ); - options_container_type::iterator get_opt_index( std::string s ); + options_container_type::const_iterator get_opt_index( const std::string& s ); }; -template <class T> -int Opts::add(char _shortname,T _default_value,const std::string& _longname,const std::string& _desc) +template < class T , class V > +T Opts::get( const V& field, const T& ) { - addflag(_shortname,_longname,_desc); - std::stringstream ss; - ss << _default_value; - storage[storage.size() - 1][ss.str()]; - return storage[storage.size() - 1].token; -} + options_container_type::const_iterator i = + std::find_if( storage.begin(), storage.end(), + std::bind2nd( detail::deref_equal<option_base*,V>(), field ) ); -template <class T> -int Opts::add(const std::string& _longname,T _default_value,const std::string& _desc) -{ - addflag(_longname,_desc); - std::stringstream ss; - ss << _default_value; - storage[storage.size() - 1][ss.str()]; - return storage[storage.size() - 1].token; -} - -template <class T> -bool Opts::is_set(T field) const -{ - options_container_type::const_iterator i = std::find( storage.begin(), storage.end(), field ); - return ( (i == storage.end()) ? false : !i->pos.empty()); -} - -template <class T> -int Opts::get_cnt(T field) const -{ - options_container_type::const_iterator i = std::find( storage.begin(), storage.end(), field ); - return ( (i == storage.end()) ? 0 : i->pos.size()); -} - -template <class V> -std::string Opts::get( V field ) -{ - options_container_type::const_iterator i = std::find( storage.begin(), storage.end(), field ); - if ( i == storage.end() ) { std::stringstream ss1; ss1 << field; - throw unknown_option( ss1.str() ); + throw unknown_option( ss1.str() ); } - if ( !i->has_arg ) { + if ( !(*i)->has_arg ) { throw std::logic_error("using Opts::get for option without arguments"); } - return i->args.empty() ? i->default_v : i->args[0]; + T res; + + (*i)->assign( res ); + + return res; } template < class T , class V > -T Opts::get( V field ) +T Opts::get( const V& field ) { - options_container_type::const_iterator i = std::find(storage.begin(), storage.end() ,field); + options_container_type::const_iterator i = + std::find_if( storage.begin(), storage.end(), + std::bind2nd( detail::deref_equal<option_base*,V>(), field ) ); if ( i == storage.end() ) { std::stringstream ss1; @@ -248,73 +504,71 @@ throw unknown_option( ss1.str() ); } - if ( !i->has_arg ) { + if ( !(*i)->has_arg ) { throw std::logic_error("using Opts::get for option without arguments"); } T res; - std::stringstream ss(i->args.empty() ? i->default_v : i->args[0]); - ss >> res; - if ( ss.fail() ) { - std::stringstream ss1; - ss1 << field; - throw arg_typemismatch(ss1.str(),i->args.empty() ? i->default_v : i->args[0]); - } + (*i)->assign( res ); return res; } -template < class V> -std::string Opts::get_default( V field ) +template <class BackInsertIterator> +void Opts::getemall( char field, BackInsertIterator bi ) { - options_container_type::const_iterator i = std::find( storage.begin(), storage.end(), field ); + options_container_type::const_iterator i = + std::find_if( storage.begin(), storage.end(), + std::bind2nd( detail::deref_equal<option_base*,char>(), field ) ); if ( i == storage.end() ) { std::stringstream ss1; ss1 << field; - throw unknown_option( ss1.str() ); + throw unknown_option(ss1.str()); } - if ( !i->has_arg ) { - throw std::logic_error("using Opts::get for option without arguments"); + if ( !(*i)->has_arg ) { + throw std::logic_error("using Opts::getemall for option without arguments"); } - - return i->default_v; + + typedef typename BackInsertIterator::container_type::value_type real_type; + + option<real_type>* opt = dynamic_cast< option<real_type> * >( *i ); + + opt->get( bi ); } -template <class T , class V> -T Opts::get_default( V field ) +template <class BackInsertIterator> +void Opts::getemall( const std::string& field, BackInsertIterator bi ) { - options_container_type::const_iterator i = std::find( storage.begin(), storage.end(), field ); + options_container_type::const_iterator i = + std::find_if( storage.begin(), storage.end(), + std::bind2nd( detail::deref_equal<option_base*,std::string>(), field ) ); if ( i == storage.end() ) { std::stringstream ss1; ss1 << field; - throw unknown_option( ss1.str() ); + throw unknown_option(ss1.str()); } - if ( !i->has_arg ) { - throw std::logic_error("using Opts::get for option without arguments"); + if ( !(*i)->has_arg ) { + throw std::logic_error("using Opts::getemall for option without arguments"); } - - T res; - std::stringstream ss(i->default_v); - ss >> res; - if ( ss.fail() ) { - std::stringstream ss1; - ss1 << field; - throw arg_typemismatch(ss1.str(),i->default_v); - } + typedef typename BackInsertIterator::container_type::value_type real_type; - return res; + option<real_type>* opt = dynamic_cast< option<real_type> * >( *i ); + + opt->get( bi ); } -template <class V , class BackInsertIterator> -void Opts::getemall( V field , BackInsertIterator bi) +template <class BackInsertIterator> +void Opts::getemall( int field, BackInsertIterator bi ) { - options_container_type::const_iterator i = std::find( storage.begin(), storage.end(), field ); + options_container_type::const_iterator i = + std::find_if( storage.begin(), storage.end(), + std::bind2nd( detail::deref_equal<option_base*,int>(), field ) ); if ( i == storage.end() ) { std::stringstream ss1; @@ -322,28 +576,39 @@ throw unknown_option(ss1.str()); } - if ( !i->has_arg ) { + if ( !(*i)->has_arg ) { throw std::logic_error("using Opts::getemall for option without arguments"); } - - if ( !i->args.empty() ) { - for ( int j = 0; j < i->args.size(); ++j) { - std::stringstream ss(i->args[j]); - ss >> *bi++; - if ( ss.fail() ) { - std::stringstream ss1; - ss1 << field; - throw arg_typemismatch(ss1.str(),i->args[j]); - } - } + typedef typename BackInsertIterator::container_type::value_type real_type; + + option<real_type>* opt = dynamic_cast< option<real_type> * >( *i ); + + opt->get( bi ); +} + +template <class BackInsertIterator> +void Opts::get_pos( char field , BackInsertIterator bi ) +{ + options_container_type::const_iterator i = + std::find_if( storage.begin(), storage.end(), + std::bind2nd( detail::deref_equal<option_base*,char>(), field ) ); + + if ( i == storage.end() ) { + std::stringstream ss1; + ss1 << field; + throw unknown_option(ss1.str()); } + + std::copy( (*i)->pos.begin(), (*i)->pos.end(), bi ); } -template <class V , class BackInsertIterator> -void Opts::get_pos( V field , BackInsertIterator bi) +template <class BackInsertIterator> +void Opts::get_pos( const std::string& field, BackInsertIterator bi ) { - options_container_type::const_iterator i = std::find( storage.begin(), storage.end(), field ); + options_container_type::const_iterator i = + std::find_if( storage.begin(), storage.end(), + std::bind2nd( detail::deref_equal<option_base*,std::string>(), field ) ); if ( i == storage.end() ) { std::stringstream ss1; @@ -351,7 +616,23 @@ throw unknown_option(ss1.str()); } - std::copy( i->pos.begin(), i->pos.end(), bi ); + std::copy( (*i)->pos.begin(), (*i)->pos.end(), bi ); } +template <class BackInsertIterator> +void Opts::get_pos( int field, BackInsertIterator bi ) +{ + options_container_type::const_iterator i = + std::find_if( storage.begin(), storage.end(), + std::bind2nd( detail::deref_equal<option_base*,int>(), field ) ); + + if ( i == storage.end() ) { + std::stringstream ss1; + ss1 << field; + throw unknown_option(ss1.str()); + } + + std::copy( (*i)->pos.begin(), (*i)->pos.end(), bi ); +} + #endif // __OPTS_H__ Modified: trunk/complement/explore/lib/exam/ut/exam_self_test.cc =================================================================== --- trunk/complement/explore/lib/exam/ut/exam_self_test.cc 2008-06-29 21:48:10 UTC (rev 1927) +++ trunk/complement/explore/lib/exam/ut/exam_self_test.cc 2008-06-29 21:48:33 UTC (rev 1928) @@ -1,7 +1,7 @@ -// -*- C++ -*- Time-stamp: <07/09/01 09:10:26 ptr> +// -*- C++ -*- Time-stamp: <08/06/30 01:27:58 ptr> /* - * Copyright (c) 2007 + * Copyright (c) 2007, 2008 * Petr Ovtchenkov * * Licensed under the Academic Free License Version 3.0 @@ -14,15 +14,8 @@ using namespace std; -int main( int argc,const char** argv) +int main( int argc, const char** argv ) { - // exam::test_suite t( "exam self test" ); - // t.add( exam_self_test, "exam self test suite" ); - // - // return t.girdle(); - - // return exam_self_test(0); - exam::test_suite t( "exam self test" ); exam_basic_test exam_basic; @@ -40,12 +33,15 @@ Opts opts; - opts.addflag( 'h', "help", "print this help message" ); - opts.addflag( 'l', "list", "list all test cases" ); - opts.add( 'r', 0, "run", "run tests by number" ); - opts.addflag( 'v', "verbose", "print status of tests within test suite" ); - opts.addflag( 't', "trace", "trace checks" ); + opts.description( "test suite for 'exam' framework" ); + opts.usage( "[options]" ); + opts << option<bool>( "print this help message", 'h', "help" ) + << option<bool>( "list all test cases", 'l', "list" ) + << option<string>( "run tests by number", 'r', "run" )["0"] + << option<bool>( "print status of tests within test suite", 'v', "verbose" ) + << option<bool>( "trace checks", 't', "trace" ); + try { opts.parse( argc, argv ); } @@ -73,7 +69,7 @@ } if ( opts.is_set( 'r' ) ) { - stringstream ss( opts.get( 'r' ) ); + stringstream ss( opts.get<string>( 'r' ) ); int n; while ( ss >> n ) { t.single( n ); @@ -84,4 +80,3 @@ return t.girdle(); } - Modified: trunk/complement/explore/lib/misc/ChangeLog =================================================================== --- trunk/complement/explore/lib/misc/ChangeLog 2008-06-29 21:48:10 UTC (rev 1927) +++ trunk/complement/explore/lib/misc/ChangeLog 2008-06-29 21:48:33 UTC (rev 1928) @@ -1,3 +1,11 @@ +2008-06-30 Petr Ovtchenkov <pt...@is...> + + * opts.h, opts.cc: revision of options framework; + insert object with type and type check into option; + default value passed via [] operator; + + * libmisc: version 1.10.0. + 2008-06-16 Petr Ovtchenkov <ye...@ya...> * opts.cc, opts.h: options parser, by Dmitry Osmakov. Modified: trunk/complement/explore/lib/misc/Makefile.inc =================================================================== --- trunk/complement/explore/lib/misc/Makefile.inc 2008-06-29 21:48:10 UTC (rev 1927) +++ trunk/complement/explore/lib/misc/Makefile.inc 2008-06-29 21:48:33 UTC (rev 1928) @@ -1,4 +1,4 @@ -# -*- Makefile -*- Time-stamp: <02/08/01 09:27:30 ptr> +# -*- Makefile -*- Time-stamp: <08/06/30 01:39:17 ptr> # I have only one reason while I should use "C++" variant of MD5 instead of "C": # names like MD5Init is wide distributed, but some cool programmers use this @@ -9,7 +9,7 @@ LIBNAME = misc MAJOR = 1 -MINOR = 9 -PATCH = 1 +MINOR = 10 +PATCH = 0 SRC_CC = CyrMoney.cc args.cc arguments.cc opts.cc SRC_C = md5.c Modified: trunk/complement/explore/lib/misc/opts.cc =================================================================== --- trunk/complement/explore/lib/misc/opts.cc 2008-06-29 21:48:10 UTC (rev 1927) +++ trunk/complement/explore/lib/misc/opts.cc 2008-06-29 21:48:33 UTC (rev 1928) @@ -1,10 +1,10 @@ -// -*- C++ -*- Time-stamp: <08/06/29 13:05:13 ptr> +// -*- C++ -*- Time-stamp: <08/06/29 22:38:24 ptr> /* * Copyright (c) 2008 * Dmitry Osmakov * - * Copyright (c) 2008 + * Copyright (c) 1997-1998, 2001, 2008 * Petr Ovtchenkov * * Licensed under the Academic Free License Version 3.0 @@ -21,22 +21,106 @@ using namespace std; -ostream& operator <<( ostream& out, const option_base& opt ) +int option_base::_count = 0; + +std::ostream& option<string>::_describe( std::ostream& out ) const { - if ( opt.shortname != 0 ) { - out << '-' << opt.shortname << (opt.has_arg ? " <val>" : "" ); - if ( !opt.longname.empty() ) { + if ( option_base::shortname != 0 ) { + out << '-' << option_base::shortname << " <string>"; + if ( !option_base::longname.empty() ) { out << ", "; } } + + if ( !option_base::longname.empty() ) { + out << "--" << option_base::longname << "=<string>"; + } - if ( !opt.longname.empty() ) { - out << "--" << opt.longname << (opt.has_arg ? "=<val>" : "" ); + if ( option_base::has_arg ) { + out << " [" << args.front() << "]\t"; + } else { + out << '\t'; } - return out << (opt.has_arg ? (string(" [") + opt.default_v + "]\t") : "\t" ) << opt.desc; + return out << option_base::desc; } +std::ostream& option<char*>::_describe( std::ostream& out ) const +{ + if ( option_base::shortname != 0 ) { + out << '-' << option_base::shortname << " <string>"; + if ( !option_base::longname.empty() ) { + out << ", "; + } + } + + if ( !option_base::longname.empty() ) { + out << "--" << option_base::longname << "=<string>"; + } + + if ( option_base::has_arg ) { + out << " [" << args.front() << "]\t"; + } else { + out << '\t'; + } + + return out << option_base::desc; +} + +bool Opts::is_set( char field ) const +{ + options_container_type::const_iterator i = + std::find_if( storage.begin(), storage.end(), + std::bind2nd( detail::deref_equal<option_base*,char>(), field ) ); + + return ( (i == storage.end()) ? false : !(*i)->pos.empty()); +} + +bool Opts::is_set( const std::string& field ) const +{ + options_container_type::const_iterator i = + std::find_if( storage.begin(), storage.end(), + std::bind2nd( detail::deref_equal<option_base*,std::string>(), field ) ); + + return ( (i == storage.end()) ? false : !(*i)->pos.empty()); +} + +bool Opts::is_set( int field ) const +{ + options_container_type::const_iterator i = + std::find_if( storage.begin(), storage.end(), + std::bind2nd( detail::deref_equal<option_base*,int>(), field ) ); + + return ( (i == storage.end()) ? false : !(*i)->pos.empty()); +} + +int Opts::get_cnt( char field ) const +{ + options_container_type::const_iterator i = + std::find_if( storage.begin(), storage.end(), + std::bind2nd( detail::deref_equal<option_base*,char>(), field ) ); + + return ( (i == storage.end()) ? 0 : (*i)->pos.size()); +} + +int Opts::get_cnt( const std::string& field ) const +{ + options_container_type::const_iterator i = + std::find_if( storage.begin(), storage.end(), + std::bind2nd( detail::deref_equal<option_base*,std::string>(), field ) ); + + return ( (i == storage.end()) ? 0 : (*i)->pos.size()); +} + +int Opts::get_cnt( int field ) const +{ + options_container_type::const_iterator i = + std::find_if( storage.begin(), storage.end(), + std::bind2nd( detail::deref_equal<option_base*,int>(), field ) ); + + return ( (i == storage.end()) ? 0 : (*i)->pos.size()); +} + string Opts::get_pname() const { return pname; } bool Opts::is_opt_name(const string& s) @@ -71,37 +155,38 @@ } // this function assumes that is_opt_name(s) = true; -Opts::options_container_type::iterator Opts::get_opt_index(string s) +Opts::options_container_type::const_iterator Opts::get_opt_index( const string& s) { assert(is_opt_name(s)); - if (s.size() == 2 && isalnum(s[1]) ) // is short name - { - options_container_type::iterator i; - for (i = storage.begin();i != storage.end();++i) - if (i->shortname == s[1]) + if (s.size() == 2 && isalnum(s[1]) ) { // is short name + options_container_type::const_iterator i = storage.begin(); + for ( ; i != storage.end(); ++i ) { + if ( (*i)->shortname == s[1]) { break; + } + } return i; } - if (s.size() > 2 && s[1] == '-') - { - options_container_type::iterator i; - s = s.substr(2); + if (s.size() > 2 && s[1] == '-') { + options_container_type::const_iterator i; + string tmp = s.substr(2); // exact match - for (i = storage.begin();i != storage.end();++i) - if (i->longname == s) + for ( i = storage.begin(); i != storage.end(); ++i ) { + if ( (*i)->longname == tmp ) { return i; + } + } - vector< options_container_type::iterator > matches; - for (i = storage.begin();i != storage.end();++i) - if (is_substr(s,i->longname)) + vector< options_container_type::const_iterator > matches; + for ( i = storage.begin();i != storage.end();++i ) { + if ( is_substr( tmp, (*i)->longname ) ) { matches.push_back(i); + } + } - if (matches.size() == 1) - return matches[0]; - else - return storage.end(); + return matches.size() == 1 ? matches[0] : storage.end(); } return storage.end(); @@ -129,32 +214,12 @@ out << "\nOptions:\n\n"; for ( options_container_type::const_iterator i = storage.begin(); i != storage.end(); ++i) { - out << *i << "\n"; + (*i)->_describe( out ) << '\n'; } } out << endl; } -int Opts::addflag( char _shortname, const string& _longname, const string& _desc ) -{ - option_base opt( _desc.c_str(), _shortname, _longname.c_str() ); - - opt.has_arg = false; - opt.token = ++free_token; - storage.push_back(opt); - return opt.token; -} - -int Opts::addflag( const string& _longname, const string& _desc ) -{ - option_base opt( _desc.c_str(), _longname.c_str() ); - - opt.has_arg = false; - opt.token = ++free_token; - storage.push_back(opt); - return opt.token; -} - void Opts::parse( int& ac, const char** av ) { pname = av[0]; @@ -168,41 +233,41 @@ string opt = av[i]; string arg; - int k = opt.find( "=" ); + string::size_type k = opt.find( "=" ); if ( k != string::npos ) { arg = opt.substr( k + 1 ); opt = opt.substr( 0, k ); } - options_container_type::iterator p = get_opt_index(opt); + options_container_type::const_iterator p = get_opt_index(opt); if ( p == storage.end() ) { throw unknown_option(opt); } - p->pos.push_back(++q); - if ( p->has_arg ) { + if ( (*p)->has_arg ) { if ( !arg.empty() ) { - p->args.push_back(arg); + (*p)->read(arg); } else { if ( (i + 1) >= ac ) { throw missing_arg(opt); } - p->args.push_back(av[++i]); + (*p)->read( av[++i] ); } } else if ( !arg.empty() ) { //unexpected arg (not exactly mismatch) throw arg_typemismatch(opt,arg); } + (*p)->pos.push_back(++q); } else if ( is_flag_group(av[i]) ) { string optgroup = av[i]; for ( int j = 1; j < optgroup.size(); j++ ) { - options_container_type::iterator p = get_opt_index(string("-") + optgroup[j]); + options_container_type::const_iterator p = get_opt_index(string("-") + optgroup[j]); if ( p == storage.end() ) { throw unknown_option( "-" + string(1,optgroup[j]) ); } - p->pos.push_back(++q); - if ( p->has_arg ) { + (*p)->pos.push_back(++q); + if ( (*p)->has_arg ) { throw missing_arg( "-" + string(1,optgroup[j]) ); } } Modified: trunk/complement/explore/lib/misc/ut/Makefile =================================================================== --- trunk/complement/explore/lib/misc/ut/Makefile 2008-06-29 21:48:10 UTC (rev 1927) +++ trunk/complement/explore/lib/misc/ut/Makefile 2008-06-29 21:48:33 UTC (rev 1928) @@ -1,4 +1,4 @@ -# -*- Makefile -*- Time-stamp: <08/06/12 15:20:10 ptr> +# -*- Makefile -*- Time-stamp: <08/06/29 19:26:11 ptr> SRCROOT := ../../.. @@ -11,15 +11,16 @@ LIBEXAM_DIR = ${CoMT_DIR}/lib/exam LIBXMT_DIR = ${CoMT_DIR}/lib/mt +LIBMISC_DIR = ${CoMT_DIR}/lib/misc ifeq ($(OSNAME),linux) -release-shared: LDFLAGS += -L${LIBEXAM_DIR}/${OUTPUT_DIR} -L${LIBXMT_DIR}/${OUTPUT_DIR} -Wl,--rpath=${LIBEXAM_DIR}/${OUTPUT_DIR}:${LIBXMT_DIR}/${OUTPUT_DIR}:${STLPORT_LIB_DIR} +release-shared: LDFLAGS += -L${LIBEXAM_DIR}/${OUTPUT_DIR} -L${LIBXMT_DIR}/${OUTPUT_DIR} -L${LIBMISC_DIR}/${OUTPUT_DIR} -Wl,--rpath=${LIBEXAM_DIR}/${OUTPUT_DIR}:${LIBXMT_DIR}/${OUTPUT_DIR}:${LIBMISC_DIR}/${OUTPUT_DIR}:${STLPORT_LIB_DIR} -dbg-shared: LDFLAGS += -L${LIBEXAM_DIR}/${OUTPUT_DIR_DBG} -L${LIBXMT_DIR}/${OUTPUT_DIR_DBG} -Wl,--rpath=${LIBEXAM_DIR}/${OUTPUT_DIR_DBG}:${LIBXMT_DIR}/${OUTPUT_DIR_DBG}:${STLPORT_LIB_DIR} +dbg-shared: LDFLAGS += -L${LIBEXAM_DIR}/${OUTPUT_DIR_DBG} -L${LIBXMT_DIR}/${OUTPUT_DIR_DBG} -L${LIBMISC_DIR}/${OUTPUT_DIR_DBG} -Wl,--rpath=${LIBEXAM_DIR}/${OUTPUT_DIR_DBG}:${LIBXMT_DIR}/${OUTPUT_DIR_DBG}:${LIBMISC_DIR}/${OUTPUT_DIR_DBG}:${STLPORT_LIB_DIR} ifndef WITHOUT_STLPORT -stldbg-shared: LDFLAGS += -L${LIBEXAM_DIR}/${OUTPUT_DIR_STLDBG} -L${LIBXMT_DIR}/${OUTPUT_DIR_STLDBG} -Wl,--rpath=${LIBEXAM_DIR}/${OUTPUT_DIR_STLDBG}:${LIBXMT_DIR}/${OUTPUT_DIR_STLDBG}:${STLPORT_LIB_DIR} +stldbg-shared: LDFLAGS += -L${LIBEXAM_DIR}/${OUTPUT_DIR_STLDBG} -L${LIBXMT_DIR}/${OUTPUT_DIR_STLDBG} -L${LIBMISC_DIR}/${OUTPUT_DIR_STLDBG} -Wl,--rpath=${LIBEXAM_DIR}/${OUTPUT_DIR_STLDBG}:${LIBXMT_DIR}/${OUTPUT_DIR_STLDBG}:${LIBMISC_DIR}/${OUTPUT_DIR_STLDBG}:${STLPORT_LIB_DIR} endif endif @@ -34,10 +35,10 @@ endif -release-shared : LDLIBS = -lexam -lxmt -dbg-shared : LDLIBS = -lexamg -lxmtg +release-shared : LDLIBS = -lexam -lxmt -lmisc +dbg-shared : LDLIBS = -lexamg -lxmtg -lmiscg ifndef WITHOUT_STLPORT -stldbg-shared : LDLIBS = -lexamstlg -lxmtstlg +stldbg-shared : LDLIBS = -lexamstlg -lxmtstlg -lmiscstlg endif ifeq ($(OSNAME),freebsd) Modified: trunk/complement/explore/lib/misc/ut/Makefile.inc =================================================================== --- trunk/complement/explore/lib/misc/ut/Makefile.inc 2008-06-29 21:48:10 UTC (rev 1927) +++ trunk/complement/explore/lib/misc/ut/Makefile.inc 2008-06-29 21:48:33 UTC (rev 1928) @@ -1,7 +1,6 @@ -# -*- makefile -*- Time-stamp: <08/05/01 12:00:01 ptr> +# -*- makefile -*- Time-stamp: <08/06/29 19:23:01 ptr> PRGNAME = misc_ut SRC_CC = unit_test.cc \ misc_test.cc misc_test_suite.cc opts_test.cc -SRC_CPP = ../opts.cpp Modified: trunk/complement/explore/lib/misc/ut/misc_test_suite.cc =================================================================== --- trunk/complement/explore/lib/misc/ut/misc_test_suite.cc 2008-06-29 21:48:10 UTC (rev 1927) +++ trunk/complement/explore/lib/misc/ut/misc_test_suite.cc 2008-06-29 21:48:33 UTC (rev 1928) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <08/05/21 12:30:07 yeti> +// -*- C++ -*- Time-stamp: <08/06/30 01:37:00 ptr> /* * Copyright (c) 2007, 2008 @@ -65,45 +65,49 @@ opts_test opts; - t.add( &opts_test::bool_option_long, opts, "simple boolean option, long" , + exam::test_suite::test_case_type tc[10]; + + tc[0] = + t.add( &opts_test::bool_option_long, opts, "simple boolean option, long" , t.add( &opts_test::bool_option, opts, "simple boolean option" ) ); - t.add( &opts_test::int_option_long, opts, "option with int parameter, long", + tc[1] = + 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::add_check_flag , opts , "add_check_flag"); - t.add( &opts_test::add_get_opt , opts , "add_get_opts"); - t.add( &opts_test::option_position,opts,"option position"); + t.add( &opts_test::add_check_flag, opts, "add_check_flag", tc[0] ); + t.add( &opts_test::add_get_opt, opts, "add_get_opts", tc[1] ); + t.add( &opts_test::option_position, opts, "option position", tc[0] ); - t.add( &opts_test::defaults, opts, "defaults" ); + t.add( &opts_test::defaults, opts, "defaults", tc[1] ); - t.add( &opts_test::bad_option, opts, "bad option" ); - t.add( &opts_test::bad_argument, opts, "bad argument" ); - t.add( &opts_test::unexpected_argument, opts, "unexpected_argument" ); - t.add( &opts_test::missing_argument, opts, "missing argument" ); + t.add( &opts_test::bad_option, opts, "bad option", tc[0] ); + t.add( &opts_test::bad_argument, opts, "bad argument", tc[1] ); + t.add( &opts_test::unexpected_argument, opts, "unexpected_argument", tc[0] ); + t.add( &opts_test::missing_argument, opts, "missing argument", tc[1] ); t.add( &opts_test::user_defined, opts, "user-defined type" ); - t.add( &opts_test::compound, opts, "compound" ); + tc[2] = t.add( &opts_test::compound, opts, "compound", tc[0] ); - t.add( &opts_test::multiple, opts,"multiple"); + tc[3] = t.add( &opts_test::multiple, opts, "multiple", tc[0] ); - t.add( &opts_test::multiple_compound, opts,"multiple_compound"); + t.add( &opts_test::multiple_compound, opts, "multiple_compound", tc + 2, tc + 4 ); - t.add( &opts_test::args, opts,"args"); + t.add( &opts_test::args, opts, "args" ); - t.add( &opts_test::stop, opts,"stop"); + t.add( &opts_test::stop, opts, "stop", tc, tc + 2 ); // check whether autocomplement works - t.add( &opts_test::autocomplement, opts,"autocomplement"); - t.add( &opts_test::autocomplement_failure, opts,"autocomplement_failure"); + tc[4] = t.add( &opts_test::autocomplement, opts, "autocomplement", tc[1] ); + t.add( &opts_test::autocomplement_failure, opts, "autocomplement_failure", tc[4] ); - t.add( &opts_test::multiple_args, opts,"multiple_args"); + t.add( &opts_test::multiple_args, opts, "multiple_args", tc[3] ); - t.add( &opts_test::help, opts, "help"); + t.add( &opts_test::help, opts, "help", tc, tc + 2 ); - t.add( &opts_test::long_string, opts, "long string"); + t.add( &opts_test::long_string, opts, "long string" ); return t.girdle(); } Modified: trunk/complement/explore/lib/misc/ut/opts_test.cc =================================================================== --- trunk/complement/explore/lib/misc/ut/opts_test.cc 2008-06-29 21:48:10 UTC (rev 1927) +++ trunk/complement/explore/lib/misc/ut/opts_test.cc 2008-06-29 21:48:33 UTC (rev 1928) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <08/06/29 13:18:16 ptr> +// -*- C++ -*- Time-stamp: <08/06/30 01:10:34 ptr> /* * Copyright (c) 2008 @@ -17,7 +17,6 @@ #include <set> #include <vector> #include <list> -#include <fstream> #include <iostream> using namespace std; @@ -29,7 +28,7 @@ Opts opts; - opts.addflag( 'h', "help", "print this help message" ); + opts << option<bool>( "print this help message", 'h', "help" ); try { opts.parse( argc, argv ); @@ -40,6 +39,8 @@ } catch ( const Opts::arg_typemismatch& e ) { } + catch ( const std::invalid_argument& e ) { + } return EXAM_RESULT; } @@ -51,7 +52,7 @@ Opts opts; - opts.addflag( 'h', "help", "print this help message" ); + opts << option<bool>( "print this help message", 'h', "help" ); try { opts.parse( argc, argv ); @@ -62,6 +63,8 @@ } catch ( const Opts::arg_typemismatch& e ) { } + catch ( const std::invalid_argument& e ) { + } return EXAM_RESULT; } @@ -74,7 +77,7 @@ Opts opts; - opts.add( 'p', 0,"port", "listen tcp port"); + opts << option<int>( "listen tcp port", 'p', "port" )[0]; try { opts.parse( argc, argv ); @@ -97,7 +100,7 @@ Opts opts; - opts.add( 'p', 0, "port", "listen tcp port"); + opts << option<int>( "listen tcp port", 'p', "port" )[0]; try { opts.parse( argc, argv ); @@ -110,6 +113,8 @@ } catch ( const Opts::arg_typemismatch& e ) { } + catch ( const std::invalid_argument& e ) { + } return EXAM_RESULT; } @@ -121,11 +126,15 @@ Opts opts; - int f_token = opts.addflag('f'); - opts.addflag('t',"tag"); - int foo_token = opts.addflag("foo"); - opts.addflag("temp","temp desc"); - int h_token = opts.addflag( 'h', "help", "print this help message" ); + int f_token = (opts << option<bool>( "", 'f' )).last_token(); + + opts << option<bool>( "", 't', "tag" ); + + int foo_token = (opts << option<bool>( "", "foo" ) ).last_token(); + + opts << option<bool>( "temp desc", "temp" ); + + int h_token = ( opts << option<bool>( "print this help message", 'h', "help" ) ).last_token(); bool exception_happens = false; try { @@ -137,6 +146,10 @@ } catch ( const Opts::arg_typemismatch& e ) { } + catch ( const std::invalid_argument& e ) { + } + catch ( ... ) { + } EXAM_CHECK( !opts.is_set("foo") ); EXAM_CHECK( !opts.is_set(foo_token) ); @@ -146,40 +159,36 @@ EXAM_CHECK( opts.is_set('t')); EXAM_CHECK( opts.is_set("temp") ); EXAM_CHECK( !opts.is_set("unknow option") ); - EXAM_CHECK( !opts.is_set(42) ); + EXAM_CHECK( !opts.is_set(h_token+1) ); - try - { + try { opts.get<int>('f'); } - catch(const logic_error& e) - { + catch(const logic_error& e) { exception_happens = true; } EXAM_CHECK( exception_happens ); - exception_happens = false; - try - { - opts.get_default<int>("tag"); - } - catch(const logic_error& e) - { - exception_happens = true; - } +// exception_happens = false; +// try +// { +// opts.get_default<int>("tag"); +// } +// catch(const logic_error& e) +// { +// exception_happens = true; +// } - EXAM_CHECK( exception_happens ); +// EXAM_CHECK( exception_happens ); exception_happens = false; - try - { + try { vector< string > vs; - opts.getemall(h_token,vs.begin()); + opts.getemall( h_token, back_inserter( vs ) ); } - catch( const logic_error& e) - { + catch ( const logic_error& e) { exception_happens = true; } @@ -195,11 +204,10 @@ Opts opts; - int t_token = opts.add('t',10); - int name_token = opts.add("name","linus"); - int port_token = opts.add('p',80,"port"); - int num_token = opts.add("num",100,"number of elements"); - + int t_token = (opts << option<int>( "", 't' )[10]).last_token(); + int name_token = (opts << option<string>( "", "name" )["linus"]).last_token(); + int port_token = (opts << option<int>( "", 'p', "port" )[80]).last_token(); + int num_token = (opts << option<int>( "number of elements", "num")[100]).last_token(); try { opts.parse( argc, argv ); @@ -216,7 +224,7 @@ EXAM_CHECK( opts.is_set(name_token) ); EXAM_CHECK( opts.get_cnt("name") == 1 ); EXAM_CHECK( opts.get<string>(name_token) == "torwalds"); - EXAM_CHECK( opts.get_default<string>("name") == "linus"); + // EXAM_CHECK( opts.get_default<string>("name") == "linus"); EXAM_CHECK( !opts.is_set('p') ); //EXAM_CHECK( !opts.is_set("num") && opts.get<int>(num_token) == opts.get_default<int>("num") ) ; @@ -230,11 +238,11 @@ Opts opts; - opts.add( 'p', 0, "port", "listen tcp port"); - opts.addflag("begin"); - int f1_token = opts.addflag("f1"); - int f2_token = opts.addflag("f2"); - opts.addflag("end"); + opts << option<int>( "listen tcp port", 'p', "port" )[0]; + opts << option<bool>( "", "begin" ); + int f1_token = (opts << option<bool>( "", "f1") ).last_token(); + int f2_token = (opts << option<bool>( "", "f2") ).last_token(); + opts << option<bool>( "", "end" ); try { opts.parse( argc, argv ); @@ -262,8 +270,7 @@ opts.get_pos(f2_token,f2_v.begin()); opts.get_pos("end",e_v.begin()); - try - { + try { opts.get_pos("unknown",u_l.begin()); } catch(const Opts::unknown_option& e) @@ -292,7 +299,7 @@ Opts opts; - opts.add( 'p', 0, "port", "listen tcp port"); + opts << option<int>( "listen tcp port", 'p', "port" )[0]; try { opts.parse( argc, argv ); @@ -305,6 +312,8 @@ } catch ( const Opts::arg_typemismatch& e ) { } + catch ( ... ) { + } return EXAM_RESULT; } @@ -316,7 +325,7 @@ Opts opts; - opts.addflag( 'h', "help", "print this help message" ); + opts << option<bool>( "print this help message", 'h', "help" ); bool exception_happens = false; @@ -330,6 +339,8 @@ } catch ( const Opts::arg_typemismatch& e ) { } + catch ( ... ) { + } EXAM_CHECK( exception_happens ); @@ -343,23 +354,26 @@ Opts opts; - opts.add( 'p', 10, "port", "listen tcp port" ); + opts << option<int>( "listen tcp port", 'p', "port" )[10]; bool exception_happens = false; - - opts.parse( argc, argv ); - try - { + try { + opts.parse( argc, argv ); // <- exception here + int t = opts.get<int>('p'); } - catch(const Opts::arg_typemismatch& e) - { + catch ( const Opts::arg_typemismatch& e ) { exception_happens = true; } + catch ( const std::invalid_argument& e ) { + exception_happens = true; + } + catch ( ... ) { + } EXAM_CHECK( exception_happens ); - EXAM_CHECK ( opts.get_default<int>('p') == 10 ); + // EXAM_CHECK ( opts.get_default<int>('p') == 10 ); return EXAM_RESULT; } @@ -371,16 +385,14 @@ Opts opts; - opts.addflag('h',"help"); + opts << option<bool>( "", 'h', "help" ); bool exception_happens = false; - try - { + try { opts.parse( argc, argv ); } - catch(const Opts::arg_typemismatch& e) - { + catch(const Opts::arg_typemismatch& e) { exception_happens = true; } @@ -396,18 +408,18 @@ Opts opts; - opts.add('n',10,"num"); + opts << option<int>( "", 'n', "num" )[10]; bool exception_happens = false; - try - { + try { opts.parse( argc, argv ); } - catch(const Opts::missing_arg& e) - { + catch(const Opts::missing_arg& e) { exception_happens = true; } + catch ( ... ) { + } EXAM_CHECK( exception_happens ); @@ -422,7 +434,7 @@ Opts opts; - opts.addflag( 'v', "verbose", "more trace messages" ); + opts << option<bool>( "more trace messages", 'v', "verbose" ); opts.parse( argc, argv ); @@ -435,7 +447,7 @@ Opts opts; - opts.addflag( 'v', "verbose", "more trace messages" ); + opts << option<bool>( "more trace messages", 'v', "verbose" ); opts.parse( argc, argv ); @@ -448,7 +460,7 @@ Opts opts; - opts.addflag( 'v', "verbose", "more trace messages" ); + opts << option<bool>( "more trace messages", 'v', "verbose" ); opts.parse( argc, argv ); @@ -458,7 +470,6 @@ return EXAM_RESULT; } - int EXAM_IMPL(opts_test::compound) { { @@ -467,9 +478,9 @@ Opts opts; - opts.addflag( 'a', "a-option", "option a" ); - opts.addflag( 'b', "b-option", "option b" ); - opts.addflag( 'c', "c-option", "option c" ); + opts << option<bool>( "option a", 'a', "a-option" ); + opts << option<bool>( "option b", 'b', "b-option" ); + opts << option<bool>( "option c", 'c', "c-option" ); opts.parse( argc, argv ); @@ -482,36 +493,40 @@ int EXAM_IMPL(opts_test::multiple_compound) { - { - const char* argv[] = { "name", "-xf","--flag", "-f", "-p=first" ,"--pa","second" }; - int argc = sizeof( argv ) / sizeof(argv[0]); + const char* argv[] = { "name", "-xf", "--flag", "-f", "-p=first", "--pa", "second" }; + int argc = sizeof( argv ) / sizeof(argv[0]); - Opts opts; + Opts opts; - opts.addflag( 'x', "x-option", "option x" ); - opts.addflag( 'f', "flag", "option f" ); + opts << option<bool>( "option x", 'x', "x-option" ); + opts << option<bool>( "option f", 'f', "flag" ); - opts.add('p',"defaultpath","path","some path"); + opts << option<string>( "some path", 'p', "path" )["defaultpath"]; - opts.parse( argc, argv ); + opts.parse( argc, argv ); - EXAM_CHECK(opts.is_set('x')); - EXAM_CHECK(opts.is_set("flag")); - EXAM_CHECK(opts.is_set('p')); - EXAM_CHECK(opts.get_cnt("flag") == 3 && opts.get_cnt('f') == 3); - vector<string> vs(2); + EXAM_CHECK(opts.is_set('x')); + EXAM_CHECK(opts.is_set("flag")); + EXAM_CHECK(opts.is_set('p')); + EXAM_CHECK(opts.get_cnt("flag") == 3 && opts.get_cnt('f') == 3); - opts.getemall("path",vs.begin()); - EXAM_CHECK( vs[0] == "first" ); - EXAM_CHECK( vs[1] == "second" ); - } + vector<string> vs; + opts.getemall( "path", back_inserter( vs ) ); + vector<string>::iterator j = vs.begin(); + + EXAM_CHECK( j != vs.end() ); + EXAM_CHECK( *j == "first" ); + ++j; + EXAM_CHECK( j != vs.end() ); + EXAM_CHECK( *j == "second" ); + ++j; + EXAM_CHECK( j == vs.end() ); + return EXAM_RESULT; } - - int EXAM_IMPL(opts_test::args) { { @@ -520,7 +535,7 @@ Opts opts; - opts.add( 'f',string("default.conf"), "config", "configuration file"); + opts << option<string>( "configuration file", 'f', "config" )["default.conf"]; opts.parse( argc, argv ); @@ -536,7 +551,7 @@ Opts opts; - opts.add( 'f', string("default.conf"), "config", "configuration file" ); + opts << option<string>( "configuration file", 'f', "config" )["default.conf"]; opts.parse( argc, argv ); @@ -552,7 +567,7 @@ Opts opts; - opts.add( 'f', string("default.conf"), "config", "configuration file" ); + opts << option<string>( "configuration file", 'f', "config" )["default.conf"]; opts.parse( argc, argv ); @@ -573,7 +588,7 @@ Opts opts; - opts.addflag( 'a', "a-option", "option a" ); + opts << option<bool>( "option a", 'a', "a-option" ); opts.parse( argc, argv ); @@ -611,20 +626,18 @@ int EXAM_IMPL(opts_test::user_defined) { - { - const char* argv[] = { "name", "-s", "1 2" }; - int argc = sizeof( argv ) / sizeof(argv[0]); + const char* argv[] = { "name", "-s", "1 2" }; + int argc = sizeof( argv ) / sizeof(argv[0]); - Opts opts; + Opts opts; - opts.add( 's', point(1,1) ,"start-point", "start point"); + opts << option<point>( "start point", 's', "start-point" )[point(1,1)]; - opts.parse( argc, argv ); + opts.parse( argc, argv ); - point p = opts.get<point>( 's' ); + point p = opts.get<point>( 's' ); - EXAM_CHECK( (p.x == 1) && (p.y == 2) ); - } + EXAM_CHECK( (p.x == 1) && (p.y == 2) ); return EXAM_RESULT; } @@ -632,73 +645,79 @@ // check whether autocomplement works int EXAM_IMPL(opts_test::autocomplement) { - { - const char* argv[] = { "name" , "--num" , "4"}; - int argc = sizeof( argv ) / sizeof(argv[0]); + const char* argv[] = { "name" , "--num", "4" }; + int argc = sizeof( argv ) / sizeof(argv[0]); - Opts opts; + Opts opts; - opts.add('n',1,"number_of_processors","number of processors" ); + opts << option<int>( "number of processors", 'n', "number_of_processors" )[1]; - opts.parse( argc, argv ); + opts.parse( argc, argv ); - EXAM_CHECK( opts.get<int>('n') == 4 ); - } + EXAM_CHECK( opts.get<int>('n') == 4 ); return EXAM_RESULT; } int EXAM_IMPL(opts_test::autocomplement_failure) { - { - const char* argv[] = { "name" , "--proc" , "4"}; - int argc = sizeof( argv ) / sizeof(argv[0]); + const char* argv[] = { "name" , "--proc" , "4" }; + int argc = sizeof( argv ) / sizeof(argv[0]); - Opts opts; + Opts opts; - opts.add('p',1,"proc_num","process number" ); - opts.add('t',string("standart"),"proc_type","process type"); + opts << option<int>( "process number", 'p', "proc_num" )[1]; + opts << option<string>( "process type", 't', "proc_type" )["standard"]; - bool exception_happens = false; + bool exception_happens = false; - try - { - opts.parse( argc, argv ); - } - catch(const Opts::unknown_option& e) - { - exception_happens = true; - } - - EXAM_CHECK( exception_happens ); + try { + opts.parse( argc, argv ); } + catch (const Opts::unknown_option& e) { + exception_happens = true; + } + catch ( ... ) { + } + EXAM_CHECK( exception_happens ); + 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]); + const char* argv[] = { "name" , "-I", "first", "-I", "second", "-I", "third" }; + int argc = sizeof( argv ) / sizeof(argv[0]); - Opts opts; + Opts opts; - opts.add('I',"/usr/include","include","include paths" ); + opts << option<string>( "include paths", 'I', "include" )[ "/usr/include" ]; - opts.parse( argc, argv ); + opts.parse( argc, argv ); - vector<string> vs(10); + vector<string> vs; - opts.getemall('I',vs.begin()); + opts.getemall( 'I', back_inserter(vs) ); - EXAM_CHECK( opts.get_default<string>("include") == "/usr/include"); + // EXAM_CHECK( opts.get_default<string>("include") == "/usr/include"); + + vector<string>::iterator j = vs.begin(); + + EXAM_CHECK( j != vs.end() ); + EXAM_CHECK( *j == "first" ); + + ++j; + EXAM_CHECK( j != vs.end() ); + EXAM_CHECK( *j == "second" ); - EXAM_CHECK( vs[0] == "first" ); - EXAM_CHECK( vs[1] == "second" ); - EXAM_CHECK( vs[2] == "third" ); - } + ++j; + EXAM_CHECK( j != vs.end() ); + EXAM_CHECK( *j == "third" ); + ++j; + EXAM_CHECK( j == vs.end() ); + return EXAM_RESULT; } @@ -714,12 +733,12 @@ opts.author( "B. L. User" ); opts.copyright( "Copyright (C) Youyoudine, 2008" ); - opts.addflag( 'h', "help", "print this help message" ); - opts.addflag( "flag", "some program flag" ); - opts.addflag( 'v', "version", "print version"); - opts.add( 'I', "/usr/include", "include", "include paths" ); - opts.add( 'p', 80, "port", "listen to tcp port" ); - opts.add( "mode", "standard", "program mode"); + opts << option<bool>( "print this help message", 'h', "help" ); + opts << option<bool>( "some program flag", "flag" ); + opts << option<bool>( "print version", 'v', "version" ); + opts << option<string>( "include paths", 'I', "include" )["/usr/include"]; + opts << option<int>( "listen to tcp port", 'p', "port" )[80]; + opts << option<string>( "program mode", "mode" )["standard"]; opts.parse( argc,argv ); @@ -746,9 +765,9 @@ -h, --help\tprint this help message\n\ --flag\tsome program flag\n\ -v, --version\tprint version\n\ --I <val>, --include=<val> [/usr/include]\tinclude paths\n\ --p <val>, --port=<val> [80]\tlisten to tcp port\n\ ---mode=<val> [standard]\tprogram mode\n\ +-I <string>, --include=<string> [/usr/include]\tinclude paths\n\ +-p <i>, --port=<i> [80]\tlisten to tcp port\n\ +--mode=<string> [standard]\tprogram mode\n\ \n"; EXAM_CHECK( s.str() == sample ); @@ -759,19 +778,29 @@ int EXAM_IMPL(opts_test::long_string) { { - const char* argv[] = { "name" , "--string" , "long string"}; + const char* argv[] = { "name", "--string", "long string" }; int argc = sizeof( argv ) / sizeof(argv[0]); Opts opts; - opts.add('s',string("default value"),"string","some string param"); + opts << option<string>( "some string param", 's', "string" )["default value"]; - EXAM_CHECK( opts.get('s') == "default value"); + opts.parse( argc, argv ); - opts.parse(argc,argv); + EXAM_CHECK( opts.get<string>( 's' ) == "long string" ); + } - EXAM_CHECK( opts.get('s') == "long string"); + { + const char* argv[] = { "name" }; + int argc = sizeof( argv ) / sizeof(argv[0]); + + Opts opts; + + opts << option<string>( "some string param", 's', "string" )["default value"]; + opts.parse( argc, argv ); + + EXAM_CHECK( opts.get<string>( 's' ) == "default value" ); } return EXAM_RESULT; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |