diff options
author | Mike Buland <eichlan@xagasoft.com> | 2010-10-27 03:27:05 +0000 |
---|---|---|
committer | Mike Buland <eichlan@xagasoft.com> | 2010-10-27 03:27:05 +0000 |
commit | 10b68e6b5e7d12c7af51b960191e1be9eb788d2e (patch) | |
tree | ccc6375726b9acaf53b1bb67bec81747b0bde223 | |
parent | 68b8b5136677435a84da7d277e78470ac4a41a64 (diff) | |
download | libbu++-10b68e6b5e7d12c7af51b960191e1be9eb788d2e.tar.gz libbu++-10b68e6b5e7d12c7af51b960191e1be9eb788d2e.tar.bz2 libbu++-10b68e6b5e7d12c7af51b960191e1be9eb788d2e.tar.xz libbu++-10b68e6b5e7d12c7af51b960191e1be9eb788d2e.zip |
Interesting tweak to the variant and optparser classes. In the Variant, it
would always fail if a const char * was passed in, it now converts these
silently to Bu::FStrings, good to know...
Also, the OptParser now uses a Variant for overrides, meaning it doesn't have
to do extra parsing, and the amount of code you have to write may be
significantly reduced. Pretty sweet, overall. There is one downside. For the
moment if you use a non-standard type or object as the target of a parameter
it always needs to have a formatter >> operator defined, even if you override
and the formatter >> operator is never called. Hopefully we can get around
this in the future.
Also, it looks like it should be relatively trivial to create conversion
functions for the variant, they'll just be global template functions that
take two parameters, source type and target type. Should be good times.
-rw-r--r-- | src/optparser.cpp | 36 | ||||
-rw-r--r-- | src/optparser.h | 28 | ||||
-rw-r--r-- | src/tools/myriad.cpp | 26 | ||||
-rw-r--r-- | src/unitsuite.cpp | 2 | ||||
-rw-r--r-- | src/variant.cpp | 6 | ||||
-rw-r--r-- | src/variant.h | 1 |
6 files changed, 56 insertions, 43 deletions
diff --git a/src/optparser.cpp b/src/optparser.cpp index 864d8ce..b81691d 100644 --- a/src/optparser.cpp +++ b/src/optparser.cpp | |||
@@ -45,7 +45,11 @@ void Bu::OptParser::parse( int argc, char **argv ) | |||
45 | { | 45 | { |
46 | sOpt.set( argv[j]+2 ); | 46 | sOpt.set( argv[j]+2 ); |
47 | } | 47 | } |
48 | try | 48 | if( !hlOption.has( sOpt ) ) |
49 | { | ||
50 | optionError( "--" + sOpt ); | ||
51 | } | ||
52 | else | ||
49 | { | 53 | { |
50 | // Long param, cool, that's easy, first search for = | 54 | // Long param, cool, that's easy, first search for = |
51 | Option *pOpt = hlOption.get( sOpt ); | 55 | Option *pOpt = hlOption.get( sOpt ); |
@@ -71,26 +75,28 @@ void Bu::OptParser::parse( int argc, char **argv ) | |||
71 | } | 75 | } |
72 | else if( sExtraParam.isSet() ) | 76 | else if( sExtraParam.isSet() ) |
73 | { | 77 | { |
74 | pOpt->pProxy->setValue( sExtraParam ); | 78 | pOpt->pProxy->setValueFromStr( sExtraParam ); |
75 | } | 79 | } |
76 | else if( argv[j+1] != '\0' ) | 80 | else if( argv[j+1] != '\0' ) |
77 | { | 81 | { |
78 | pOpt->pProxy->setValue( argv[j+1] ); | 82 | pOpt->pProxy->setValueFromStr( argv[j+1] ); |
79 | j++; | 83 | j++; |
80 | } | 84 | } |
81 | } | 85 | } |
82 | } | 86 | } |
83 | catch( Bu::HashException &e ) | ||
84 | { | ||
85 | optionError( "--" + sOpt ); | ||
86 | } | ||
87 | } | 87 | } |
88 | else | 88 | else |
89 | { | 89 | { |
90 | int iCPos; | 90 | int iCPos; |
91 | for( iCPos = 1; argv[j][iCPos] != '\0'; iCPos++ ) | 91 | for( iCPos = 1; argv[j][iCPos] != '\0'; iCPos++ ) |
92 | { | 92 | { |
93 | try | 93 | if( !hsOption.has( argv[j][iCPos] ) ) |
94 | { | ||
95 | Bu::FString sOpt("-"); | ||
96 | sOpt += argv[j][iCPos]; | ||
97 | optionError( sOpt ); | ||
98 | } | ||
99 | else | ||
94 | { | 100 | { |
95 | Option *pOpt = hsOption.get( argv[j][iCPos] ); | 101 | Option *pOpt = hsOption.get( argv[j][iCPos] ); |
96 | char buf[2] = {argv[j][iCPos], '\0'}; | 102 | char buf[2] = {argv[j][iCPos], '\0'}; |
@@ -123,14 +129,14 @@ void Bu::OptParser::parse( int argc, char **argv ) | |||
123 | } | 129 | } |
124 | else if( argv[j][iCPos+1] != '\0' ) | 130 | else if( argv[j][iCPos+1] != '\0' ) |
125 | { | 131 | { |
126 | pOpt->pProxy->setValue( | 132 | pOpt->pProxy->setValueFromStr( |
127 | argv[j]+iCPos+1 | 133 | argv[j]+iCPos+1 |
128 | ); | 134 | ); |
129 | break; | 135 | break; |
130 | } | 136 | } |
131 | else if( argv[j+1] ) | 137 | else if( argv[j+1] ) |
132 | { | 138 | { |
133 | pOpt->pProxy->setValue( | 139 | pOpt->pProxy->setValueFromStr( |
134 | argv[j+1] | 140 | argv[j+1] |
135 | ); | 141 | ); |
136 | j++; | 142 | j++; |
@@ -138,12 +144,6 @@ void Bu::OptParser::parse( int argc, char **argv ) | |||
138 | } | 144 | } |
139 | } | 145 | } |
140 | } | 146 | } |
141 | catch( Bu::HashException &e ) | ||
142 | { | ||
143 | Bu::FString sOpt("-"); | ||
144 | sOpt += argv[j][iCPos]; | ||
145 | optionError( sOpt ); | ||
146 | } | ||
147 | } | 147 | } |
148 | } | 148 | } |
149 | } | 149 | } |
@@ -176,12 +176,12 @@ void Bu::OptParser::addOption( const Option &opt ) | |||
176 | hlOption.insert( opt.sOpt, &lOption.last() ); | 176 | hlOption.insert( opt.sOpt, &lOption.last() ); |
177 | } | 177 | } |
178 | 178 | ||
179 | void Bu::OptParser::setOverride( char cOpt, const Bu::FString &sOverride ) | 179 | void Bu::OptParser::setOverride( char cOpt, const Bu::Variant &sOverride ) |
180 | { | 180 | { |
181 | hsOption.get( cOpt )->sOverride = sOverride; | 181 | hsOption.get( cOpt )->sOverride = sOverride; |
182 | } | 182 | } |
183 | 183 | ||
184 | void Bu::OptParser::setOverride( const Bu::FString &sOpt, const Bu::FString &sOverride ) | 184 | void Bu::OptParser::setOverride( const Bu::FString &sOpt, const Bu::Variant &sOverride ) |
185 | { | 185 | { |
186 | hlOption.get( sOpt )->sOverride = sOverride; | 186 | hlOption.get( sOpt )->sOverride = sOverride; |
187 | } | 187 | } |
diff --git a/src/optparser.h b/src/optparser.h index 2936a4b..7ec69e5 100644 --- a/src/optparser.h +++ b/src/optparser.h | |||
@@ -15,6 +15,7 @@ | |||
15 | #include "bu/array.h" | 15 | #include "bu/array.h" |
16 | #include "bu/membuf.h" | 16 | #include "bu/membuf.h" |
17 | #include "bu/formatter.h" | 17 | #include "bu/formatter.h" |
18 | #include "bu/variant.h" | ||
18 | 19 | ||
19 | namespace Bu | 20 | namespace Bu |
20 | { | 21 | { |
@@ -40,7 +41,8 @@ namespace Bu | |||
40 | _ValueProxy(); | 41 | _ValueProxy(); |
41 | virtual ~_ValueProxy(); | 42 | virtual ~_ValueProxy(); |
42 | 43 | ||
43 | virtual void setValue( const Bu::FString & )=0; | 44 | virtual void setValueFromStr( const Bu::FString & )=0; |
45 | virtual void setValue( const Bu::Variant &vVar )=0; | ||
44 | virtual _ValueProxy *clone()=0; | 46 | virtual _ValueProxy *clone()=0; |
45 | }; | 47 | }; |
46 | 48 | ||
@@ -57,12 +59,28 @@ namespace Bu | |||
57 | { | 59 | { |
58 | } | 60 | } |
59 | 61 | ||
60 | virtual void setValue( const Bu::FString &sVal ) | 62 | virtual void setValueFromStr( const Bu::FString &sVal ) |
61 | { | 63 | { |
62 | Bu::MemBuf mb( sVal ); | 64 | Bu::MemBuf mb( sVal ); |
63 | Bu::Formatter f( mb ); | 65 | Bu::Formatter f( mb ); |
64 | f >> v; | 66 | f >> v; |
65 | } | 67 | } |
68 | |||
69 | virtual void setValue( const Bu::Variant &vVar ) | ||
70 | { | ||
71 | if( vVar.getType() == typeid(ptype) ) | ||
72 | { | ||
73 | v = vVar.get<ptype>(); | ||
74 | } | ||
75 | else if( vVar.getType() == typeid(Bu::FString) ) | ||
76 | { | ||
77 | setValueFromStr( vVar.get<Bu::FString>() ); | ||
78 | } | ||
79 | else | ||
80 | { | ||
81 | setValueFromStr( vVar.toString() ); | ||
82 | } | ||
83 | } | ||
66 | 84 | ||
67 | virtual _ValueProxy *clone() | 85 | virtual _ValueProxy *clone() |
68 | { | 86 | { |
@@ -87,7 +105,7 @@ namespace Bu | |||
87 | Bu::FString sHelp; | 105 | Bu::FString sHelp; |
88 | OptionSignal sUsed; | 106 | OptionSignal sUsed; |
89 | _ValueProxy *pProxy; | 107 | _ValueProxy *pProxy; |
90 | Bu::FString sOverride; | 108 | Bu::Variant sOverride; |
91 | Bu::FString sHelpDefault; | 109 | Bu::FString sHelpDefault; |
92 | }; | 110 | }; |
93 | 111 | ||
@@ -162,9 +180,9 @@ namespace Bu | |||
162 | addOption( sUsed, cOpt, "", sHelp ); | 180 | addOption( sUsed, cOpt, "", sHelp ); |
163 | } | 181 | } |
164 | 182 | ||
165 | void setOverride( char cOpt, const Bu::FString &sOverride ); | 183 | void setOverride( char cOpt, const Bu::Variant &sOverride ); |
166 | void setOverride( const Bu::FString &sOpt, | 184 | void setOverride( const Bu::FString &sOpt, |
167 | const Bu::FString &sOverride ); | 185 | const Bu::Variant &sOverride ); |
168 | 186 | ||
169 | void setHelpDefault( const Bu::FString &sOpt, const Bu::FString &sTxt ); | 187 | void setHelpDefault( const Bu::FString &sOpt, const Bu::FString &sTxt ); |
170 | 188 | ||
diff --git a/src/tools/myriad.cpp b/src/tools/myriad.cpp index 73ceba1..c6a3a4d 100644 --- a/src/tools/myriad.cpp +++ b/src/tools/myriad.cpp | |||
@@ -56,11 +56,11 @@ public: | |||
56 | addOption( iStream, 's', "stream", "Substream to work with."); | 56 | addOption( iStream, 's', "stream", "Substream to work with."); |
57 | addOption( sSrc, "src", "Source file for copying into a Myriad file."); | 57 | addOption( sSrc, "src", "Source file for copying into a Myriad file."); |
58 | 58 | ||
59 | setOverride( "create", "create" ); | 59 | setOverride( "create", modeCreate ); |
60 | setOverride( "info", "info" ); | 60 | setOverride( "info", modeInfo ); |
61 | setOverride( "new", "new" ); | 61 | setOverride( "new", modeStreamNew ); |
62 | setOverride( "dump", "dump" ); | 62 | setOverride( "dump", modeStreamDump ); |
63 | setOverride( "put", "put" ); | 63 | setOverride( "put", modeStreamPut ); |
64 | 64 | ||
65 | parse( argc, argv ); | 65 | parse( argc, argv ); |
66 | } | 66 | } |
@@ -73,21 +73,9 @@ public: | |||
73 | Bu::FString sSrc; | 73 | Bu::FString sSrc; |
74 | }; | 74 | }; |
75 | 75 | ||
76 | Bu::Formatter &operator>>( Bu::Formatter &f, Mode &m ) | 76 | Bu::Formatter &operator>>( Bu::Formatter &f, Mode &e ) |
77 | { | 77 | { |
78 | Bu::FString sTok = f.readToken(); | 78 | sio << "Uh oh, the formatter was called..." << sio.nl; |
79 | if( sTok == "create" ) | ||
80 | m = modeCreate; | ||
81 | else if( sTok == "info" ) | ||
82 | m = modeInfo; | ||
83 | else if( sTok == "new" ) | ||
84 | m = modeStreamNew; | ||
85 | else if( sTok == "dump" ) | ||
86 | m = modeStreamDump; | ||
87 | else if( sTok == "put" ) | ||
88 | m = modeStreamPut; | ||
89 | else | ||
90 | m = modeNone; | ||
91 | return f; | 79 | return f; |
92 | } | 80 | } |
93 | 81 | ||
diff --git a/src/unitsuite.cpp b/src/unitsuite.cpp index 7a20128..ce6d037 100644 --- a/src/unitsuite.cpp +++ b/src/unitsuite.cpp | |||
@@ -40,7 +40,7 @@ int Bu::UnitSuite::run( int argc, char *argv[] ) | |||
40 | p.addOption( Bu::slot( this, &Bu::UnitSuite::onListCases ), 'l', "list", | 40 | p.addOption( Bu::slot( this, &Bu::UnitSuite::onListCases ), 'l', "list", |
41 | "List available test cases." ); | 41 | "List available test cases." ); |
42 | p.addOption( bCleanup, "no-cleanup", "Don't erase temp files."); | 42 | p.addOption( bCleanup, "no-cleanup", "Don't erase temp files."); |
43 | p.setOverride( "no-cleanup", "false" ); | 43 | p.setOverride( "no-cleanup", false ); |
44 | p.addHelpOption(); | 44 | p.addHelpOption(); |
45 | p.parse( argc, argv ); | 45 | p.parse( argc, argv ); |
46 | 46 | ||
diff --git a/src/variant.cpp b/src/variant.cpp index a66ec39..a239e0f 100644 --- a/src/variant.cpp +++ b/src/variant.cpp | |||
@@ -34,6 +34,12 @@ Bu::Variant::Variant( const Variant &v ) : | |||
34 | } | 34 | } |
35 | } | 35 | } |
36 | 36 | ||
37 | Bu::Variant::Variant( const char *t ) : | ||
38 | pCore( NULL ) | ||
39 | { | ||
40 | set( Bu::FString( t ) ); | ||
41 | } | ||
42 | |||
37 | Bu::Variant::~Variant() | 43 | Bu::Variant::~Variant() |
38 | { | 44 | { |
39 | if( pCore ) | 45 | if( pCore ) |
diff --git a/src/variant.h b/src/variant.h index 5482ee3..8e1203c 100644 --- a/src/variant.h +++ b/src/variant.h | |||
@@ -98,6 +98,7 @@ namespace Bu | |||
98 | public: | 98 | public: |
99 | Variant(); | 99 | Variant(); |
100 | Variant( const Variant &v ); | 100 | Variant( const Variant &v ); |
101 | Variant( const char *t ); | ||
101 | template<class t> | 102 | template<class t> |
102 | Variant( const t &v ) : | 103 | Variant( const t &v ) : |
103 | pCore( new VariantType<t>() ) | 104 | pCore( new VariantType<t>() ) |