diff options
author | Mike Buland <eichlan@xagasoft.com> | 2009-12-18 08:59:16 +0000 |
---|---|---|
committer | Mike Buland <eichlan@xagasoft.com> | 2009-12-18 08:59:16 +0000 |
commit | 146930268a695dcc0432599d625ec3eb7e74025e (patch) | |
tree | a944d13981ed055b337757953014ed1e2d45e19c /src | |
parent | 0d3d73fb0cacd3d1cf7eb8b83ba87f8b740b871a (diff) | |
download | libbu++-146930268a695dcc0432599d625ec3eb7e74025e.tar.gz libbu++-146930268a695dcc0432599d625ec3eb7e74025e.tar.bz2 libbu++-146930268a695dcc0432599d625ec3eb7e74025e.tar.xz libbu++-146930268a695dcc0432599d625ec3eb7e74025e.zip |
The OptParser still needs help banners and more helper functions, but otherwise,
it's done. It works great, and provides much flexibility and usefulness.
It now relies on the input side of the Formatter class, which at the moment
supports reading strings...not real useful yet...
Next up, adding readers for numbers and such, then it'll be mostly complete.
Also, fixed a bug when copying uninitialized signal objects.
Diffstat (limited to '')
-rw-r--r-- | src/formatter.cpp | 172 | ||||
-rw-r--r-- | src/formatter.h | 54 | ||||
-rw-r--r-- | src/optparser.cpp | 105 | ||||
-rw-r--r-- | src/optparser.h | 59 | ||||
-rw-r--r-- | src/signals.h | 12 | ||||
-rw-r--r-- | src/tests/optparser.cpp | 5 |
6 files changed, 289 insertions, 118 deletions
diff --git a/src/formatter.cpp b/src/formatter.cpp index 830e527..5ab1b3f 100644 --- a/src/formatter.cpp +++ b/src/formatter.cpp | |||
@@ -9,8 +9,8 @@ | |||
9 | 9 | ||
10 | #include <string.h> | 10 | #include <string.h> |
11 | 11 | ||
12 | Bu::Formatter::Formatter( Stream &rOut ) : | 12 | Bu::Formatter::Formatter( Stream &rStream ) : |
13 | rOut( rOut ), | 13 | rStream( rStream ), |
14 | uIndent( 0 ), | 14 | uIndent( 0 ), |
15 | cIndent( '\t' ) | 15 | cIndent( '\t' ) |
16 | { | 16 | { |
@@ -22,12 +22,12 @@ Bu::Formatter::~Formatter() | |||
22 | 22 | ||
23 | void Bu::Formatter::write( const Bu::FString &sStr ) | 23 | void Bu::Formatter::write( const Bu::FString &sStr ) |
24 | { | 24 | { |
25 | rOut.write( sStr ); | 25 | rStream.write( sStr ); |
26 | } | 26 | } |
27 | 27 | ||
28 | void Bu::Formatter::write( const void *sStr, int iLen ) | 28 | void Bu::Formatter::write( const void *sStr, int iLen ) |
29 | { | 29 | { |
30 | rOut.write( sStr, iLen ); | 30 | rStream.write( sStr, iLen ); |
31 | } | 31 | } |
32 | 32 | ||
33 | void Bu::Formatter::writeAligned( const Bu::FString &sStr ) | 33 | void Bu::Formatter::writeAligned( const Bu::FString &sStr ) |
@@ -111,6 +111,36 @@ void Bu::Formatter::writeAligned( const char *sStr, int iLen ) | |||
111 | usedFormat(); | 111 | usedFormat(); |
112 | } | 112 | } |
113 | 113 | ||
114 | Bu::FString Bu::Formatter::readToken() | ||
115 | { | ||
116 | Bu::FString sRet; | ||
117 | for(;;) | ||
118 | { | ||
119 | char buf; | ||
120 | int iRead = rStream.read( &buf, 1 ); | ||
121 | if( iRead == 0 ) | ||
122 | return sRet; | ||
123 | if( buf == ' ' || buf == '\t' || buf == '\n' || buf == '\r' ) | ||
124 | continue; | ||
125 | else | ||
126 | { | ||
127 | sRet += buf; | ||
128 | break; | ||
129 | } | ||
130 | } | ||
131 | for(;;) | ||
132 | { | ||
133 | char buf; | ||
134 | int iRead = rStream.read( &buf, 1 ); | ||
135 | if( iRead == 0 ) | ||
136 | return sRet; | ||
137 | if( buf == ' ' || buf == '\t' || buf == '\n' || buf == '\r' ) | ||
138 | return sRet; | ||
139 | else | ||
140 | sRet += buf; | ||
141 | } | ||
142 | } | ||
143 | |||
114 | void Bu::Formatter::incIndent() | 144 | void Bu::Formatter::incIndent() |
115 | { | 145 | { |
116 | if( uIndent < 0xFFU ) | 146 | if( uIndent < 0xFFU ) |
@@ -192,137 +222,143 @@ Bu::Formatter::Fmt &Bu::Formatter::Fmt::caps( bool bCaps ) | |||
192 | return *this; | 222 | return *this; |
193 | } | 223 | } |
194 | 224 | ||
195 | Bu::Formatter &Bu::operator<<( Bu::Formatter &rOut, const Bu::Formatter::Fmt &f ) | 225 | Bu::Formatter &Bu::operator<<( Bu::Formatter &f, const Bu::Formatter::Fmt &fmt ) |
196 | { | 226 | { |
197 | rOut.setTempFormat( f ); | 227 | f.setTempFormat( fmt ); |
198 | return rOut; | 228 | return f; |
199 | } | 229 | } |
200 | 230 | ||
201 | Bu::Formatter &Bu::operator<<( Bu::Formatter &rOut, Bu::Formatter::Special s ) | 231 | Bu::Formatter &Bu::operator<<( Bu::Formatter &f, Bu::Formatter::Special s ) |
202 | { | 232 | { |
203 | switch( s ) | 233 | switch( s ) |
204 | { | 234 | { |
205 | case Formatter::nl: | 235 | case Formatter::nl: |
206 | { | 236 | { |
207 | rOut.write("\n", 1 ); | 237 | f.write("\n", 1 ); |
208 | char ci = rOut.getIndentChar(); | 238 | char ci = f.getIndentChar(); |
209 | for( int j = 0; j < rOut.getIndent(); j++ ) | 239 | for( int j = 0; j < f.getIndent(); j++ ) |
210 | rOut.write( &ci, 1 ); | 240 | f.write( &ci, 1 ); |
211 | } | 241 | } |
212 | break; | 242 | break; |
213 | 243 | ||
214 | case Formatter::flush: | 244 | case Formatter::flush: |
215 | rOut.doFlush(); | 245 | f.doFlush(); |
216 | break; | 246 | break; |
217 | } | 247 | } |
218 | return rOut; | 248 | return f; |
249 | } | ||
250 | |||
251 | Bu::Formatter &Bu::operator<<( Bu::Formatter &f, const char *sStr ) | ||
252 | { | ||
253 | f.writeAligned( sStr, strlen( sStr ) ); | ||
254 | return f; | ||
219 | } | 255 | } |
220 | 256 | ||
221 | Bu::Formatter &Bu::operator<<( Bu::Formatter &rOut, const char *sStr ) | 257 | Bu::Formatter &Bu::operator<<( Bu::Formatter &f, char *sStr ) |
222 | { | 258 | { |
223 | rOut.writeAligned( sStr, strlen( sStr ) ); | 259 | f.writeAligned( sStr, strlen( sStr ) ); |
224 | return rOut; | 260 | return f; |
225 | } | 261 | } |
226 | 262 | ||
227 | Bu::Formatter &Bu::operator<<( Bu::Formatter &rOut, char *sStr ) | 263 | Bu::Formatter &Bu::operator<<( Bu::Formatter &f, const Bu::FString &sStr ) |
228 | { | 264 | { |
229 | rOut.writeAligned( sStr, strlen( sStr ) ); | 265 | f.writeAligned( sStr ); |
230 | return rOut; | 266 | return f; |
231 | } | 267 | } |
232 | 268 | ||
233 | Bu::Formatter &Bu::operator<<( Bu::Formatter &rOut, const Bu::FString &sStr ) | 269 | Bu::Formatter &Bu::operator<<( Bu::Formatter &f, signed char c ) |
234 | { | 270 | { |
235 | rOut.writeAligned( sStr ); | 271 | f.write( (char *)&c, 1 ); |
236 | return rOut; | 272 | return f; |
237 | } | 273 | } |
238 | 274 | ||
239 | Bu::Formatter &Bu::operator<<( Bu::Formatter &rOut, signed char c ) | 275 | Bu::Formatter &Bu::operator<<( Bu::Formatter &f, char c ) |
240 | { | 276 | { |
241 | rOut.write( (char *)&c, 1 ); | 277 | f.write( (char *)&c, 1 ); |
242 | return rOut; | 278 | return f; |
243 | } | 279 | } |
244 | 280 | ||
245 | Bu::Formatter &Bu::operator<<( Bu::Formatter &rOut, char c ) | 281 | Bu::Formatter &Bu::operator<<( Bu::Formatter &f, unsigned char c ) |
246 | { | 282 | { |
247 | rOut.write( (char *)&c, 1 ); | 283 | f.write( (char *)&c, 1 ); |
248 | return rOut; | 284 | return f; |
249 | } | 285 | } |
250 | 286 | ||
251 | Bu::Formatter &Bu::operator<<( Bu::Formatter &rOut, unsigned char c ) | 287 | Bu::Formatter &Bu::operator<<( Bu::Formatter &f, signed short i ) |
252 | { | 288 | { |
253 | rOut.write( (char *)&c, 1 ); | 289 | f.ifmt<signed short>( i ); |
254 | return rOut; | 290 | return f; |
255 | } | 291 | } |
256 | 292 | ||
257 | Bu::Formatter &Bu::operator<<( Bu::Formatter &rOut, signed short i ) | 293 | Bu::Formatter &Bu::operator<<( Bu::Formatter &f, unsigned short i ) |
258 | { | 294 | { |
259 | rOut.ifmt<signed short>( i ); | 295 | f.ufmt<unsigned short>( i ); |
260 | return rOut; | 296 | return f; |
261 | } | 297 | } |
262 | 298 | ||
263 | Bu::Formatter &Bu::operator<<( Bu::Formatter &rOut, unsigned short i ) | 299 | Bu::Formatter &Bu::operator<<( Bu::Formatter &f, signed int i ) |
264 | { | 300 | { |
265 | rOut.ufmt<unsigned short>( i ); | 301 | f.ifmt<signed int>( i ); |
266 | return rOut; | 302 | return f; |
267 | } | 303 | } |
268 | 304 | ||
269 | Bu::Formatter &Bu::operator<<( Bu::Formatter &rOut, signed int i ) | 305 | Bu::Formatter &Bu::operator<<( Bu::Formatter &f, unsigned int i ) |
270 | { | 306 | { |
271 | rOut.ifmt<signed int>( i ); | 307 | f.ufmt<unsigned int>( i ); |
272 | return rOut; | 308 | return f; |
273 | } | 309 | } |
274 | 310 | ||
275 | Bu::Formatter &Bu::operator<<( Bu::Formatter &rOut, unsigned int i ) | 311 | Bu::Formatter &Bu::operator<<( Bu::Formatter &f, signed long i ) |
276 | { | 312 | { |
277 | rOut.ufmt<unsigned int>( i ); | 313 | f.ifmt<signed long>( i ); |
278 | return rOut; | 314 | return f; |
279 | } | 315 | } |
280 | 316 | ||
281 | Bu::Formatter &Bu::operator<<( Bu::Formatter &rOut, signed long i ) | 317 | Bu::Formatter &Bu::operator<<( Bu::Formatter &f, unsigned long i ) |
282 | { | 318 | { |
283 | rOut.ifmt<signed long>( i ); | 319 | f.ufmt<unsigned long>( i ); |
284 | return rOut; | 320 | return f; |
285 | } | 321 | } |
286 | 322 | ||
287 | Bu::Formatter &Bu::operator<<( Bu::Formatter &rOut, unsigned long i ) | 323 | Bu::Formatter &Bu::operator<<( Bu::Formatter &f, signed long long i ) |
288 | { | 324 | { |
289 | rOut.ufmt<unsigned long>( i ); | 325 | f.ifmt<signed long long>( i ); |
290 | return rOut; | 326 | return f; |
291 | } | 327 | } |
292 | 328 | ||
293 | Bu::Formatter &Bu::operator<<( Bu::Formatter &rOut, signed long long i ) | 329 | Bu::Formatter &Bu::operator<<( Bu::Formatter &f, unsigned long long i ) |
294 | { | 330 | { |
295 | rOut.ifmt<signed long long>( i ); | 331 | f.ufmt<unsigned long long>( i ); |
296 | return rOut; | 332 | return f; |
297 | } | 333 | } |
298 | 334 | ||
299 | Bu::Formatter &Bu::operator<<( Bu::Formatter &rOut, unsigned long long i ) | 335 | Bu::Formatter &Bu::operator<<( Bu::Formatter &f, float flt ) |
300 | { | 336 | { |
301 | rOut.ufmt<unsigned long long>( i ); | 337 | f.ffmt<float>( flt ); |
302 | return rOut; | 338 | return f; |
303 | } | 339 | } |
304 | 340 | ||
305 | Bu::Formatter &Bu::operator<<( Bu::Formatter &rOut, float f ) | 341 | Bu::Formatter &Bu::operator<<( Bu::Formatter &f, double flt ) |
306 | { | 342 | { |
307 | rOut.ffmt<float>( f ); | 343 | f.ffmt<double>( flt ); |
308 | return rOut; | 344 | return f; |
309 | } | 345 | } |
310 | 346 | ||
311 | Bu::Formatter &Bu::operator<<( Bu::Formatter &rOut, double f ) | 347 | Bu::Formatter &Bu::operator<<( Bu::Formatter &f, long double flt ) |
312 | { | 348 | { |
313 | rOut.ffmt<double>( f ); | 349 | f.ffmt<long double>( flt ); |
314 | return rOut; | 350 | return f; |
315 | } | 351 | } |
316 | 352 | ||
317 | Bu::Formatter &Bu::operator<<( Bu::Formatter &rOut, long double f ) | 353 | Bu::Formatter &Bu::operator<<( Bu::Formatter &f, bool b ) |
318 | { | 354 | { |
319 | rOut.ffmt<long double>( f ); | 355 | f.writeAligned( b?("true"):("false") ); |
320 | return rOut; | 356 | return f; |
321 | } | 357 | } |
322 | 358 | ||
323 | Bu::Formatter &Bu::operator<<( Bu::Formatter &rOut, bool b ) | 359 | Bu::Formatter &Bu::operator>>( Bu::Formatter &f, Bu::FString &sStr ) |
324 | { | 360 | { |
325 | rOut.writeAligned( b?("true"):("false") ); | 361 | sStr = f.readToken(); |
326 | return rOut; | 362 | return f; |
327 | } | 363 | } |
328 | 364 | ||
diff --git a/src/formatter.h b/src/formatter.h index db144eb..aec5c5d 100644 --- a/src/formatter.h +++ b/src/formatter.h | |||
@@ -15,7 +15,7 @@ namespace Bu | |||
15 | class Formatter | 15 | class Formatter |
16 | { | 16 | { |
17 | public: | 17 | public: |
18 | Formatter( Stream &rOut ); | 18 | Formatter( Stream &rStream ); |
19 | virtual ~Formatter(); | 19 | virtual ~Formatter(); |
20 | 20 | ||
21 | typedef struct Fmt | 21 | typedef struct Fmt |
@@ -103,6 +103,8 @@ namespace Bu | |||
103 | void writeAligned( const Bu::FString &sStr ); | 103 | void writeAligned( const Bu::FString &sStr ); |
104 | void writeAligned( const char *sStr, int iLen ); | 104 | void writeAligned( const char *sStr, int iLen ); |
105 | 105 | ||
106 | Bu::FString readToken(); | ||
107 | |||
106 | void incIndent(); | 108 | void incIndent(); |
107 | void decIndent(); | 109 | void decIndent(); |
108 | void setIndent( uint8_t uLevel ); | 110 | void setIndent( uint8_t uLevel ); |
@@ -206,11 +208,11 @@ namespace Bu | |||
206 | 208 | ||
207 | void doFlush() | 209 | void doFlush() |
208 | { | 210 | { |
209 | rOut.flush(); | 211 | rStream.flush(); |
210 | } | 212 | } |
211 | 213 | ||
212 | private: | 214 | private: |
213 | Stream &rOut; | 215 | Stream &rStream; |
214 | Fmt fLast; | 216 | Fmt fLast; |
215 | bool bTempFmt; | 217 | bool bTempFmt; |
216 | uint8_t uIndent; | 218 | uint8_t uIndent; |
@@ -219,31 +221,33 @@ namespace Bu | |||
219 | 221 | ||
220 | typedef Formatter::Fmt Fmt; | 222 | typedef Formatter::Fmt Fmt; |
221 | 223 | ||
222 | Formatter &operator<<( Formatter &rOut, const Formatter::Fmt &f ); | 224 | Formatter &operator<<( Formatter &f, const Formatter::Fmt &fmt ); |
223 | Formatter &operator<<( Formatter &rOut, Formatter::Special s ); | 225 | Formatter &operator<<( Formatter &f, Formatter::Special s ); |
224 | Formatter &operator<<( Formatter &rOut, const char *sStr ); | 226 | Formatter &operator<<( Formatter &f, const char *sStr ); |
225 | Formatter &operator<<( Formatter &rOut, char *sStr ); | 227 | Formatter &operator<<( Formatter &f, char *sStr ); |
226 | Formatter &operator<<( Formatter &rOut, const Bu::FString &sStr ); | 228 | Formatter &operator<<( Formatter &f, const Bu::FString &sStr ); |
227 | Formatter &operator<<( Formatter &rOut, signed char c ); | 229 | Formatter &operator<<( Formatter &f, signed char c ); |
228 | Formatter &operator<<( Formatter &rOut, char c ); | 230 | Formatter &operator<<( Formatter &f, char c ); |
229 | Formatter &operator<<( Formatter &rOut, unsigned char c ); | 231 | Formatter &operator<<( Formatter &f, unsigned char c ); |
230 | Formatter &operator<<( Formatter &rOut, signed short i ); | 232 | Formatter &operator<<( Formatter &f, signed short i ); |
231 | Formatter &operator<<( Formatter &rOut, unsigned short i ); | 233 | Formatter &operator<<( Formatter &f, unsigned short i ); |
232 | Formatter &operator<<( Formatter &rOut, signed int i ); | 234 | Formatter &operator<<( Formatter &f, signed int i ); |
233 | Formatter &operator<<( Formatter &rOut, unsigned int i ); | 235 | Formatter &operator<<( Formatter &f, unsigned int i ); |
234 | Formatter &operator<<( Formatter &rOut, signed long i ); | 236 | Formatter &operator<<( Formatter &f, signed long i ); |
235 | Formatter &operator<<( Formatter &rOut, unsigned long i ); | 237 | Formatter &operator<<( Formatter &f, unsigned long i ); |
236 | Formatter &operator<<( Formatter &rOut, signed long long i ); | 238 | Formatter &operator<<( Formatter &f, signed long long i ); |
237 | Formatter &operator<<( Formatter &rOut, unsigned long long i ); | 239 | Formatter &operator<<( Formatter &f, unsigned long long i ); |
238 | Formatter &operator<<( Formatter &rOut, float f ); | 240 | Formatter &operator<<( Formatter &f, float flt ); |
239 | Formatter &operator<<( Formatter &rOut, double f ); | 241 | Formatter &operator<<( Formatter &f, double flt ); |
240 | Formatter &operator<<( Formatter &rOut, long double f ); | 242 | Formatter &operator<<( Formatter &f, long double flt ); |
241 | Formatter &operator<<( Formatter &rOut, bool b ); | 243 | Formatter &operator<<( Formatter &f, bool b ); |
244 | |||
245 | Formatter &operator>>( Formatter &f, Bu::FString &sStr ); | ||
242 | 246 | ||
243 | template<typename type> | 247 | template<typename type> |
244 | Formatter &operator<<( Formatter &rOut, const type *p ) | 248 | Formatter &operator<<( Formatter &f, const type *p ) |
245 | { | 249 | { |
246 | return rOut << "0x" << Fmt::hex(sizeof(ptrdiff_t)*2) << (ptrdiff_t)(p); | 250 | return f << "0x" << Fmt::hex(sizeof(ptrdiff_t)*2) << (ptrdiff_t)(p); |
247 | } | 251 | } |
248 | }; | 252 | }; |
249 | 253 | ||
diff --git a/src/optparser.cpp b/src/optparser.cpp index f99dd85..2a8e64b 100644 --- a/src/optparser.cpp +++ b/src/optparser.cpp | |||
@@ -28,28 +28,48 @@ void Bu::OptParser::parse( int argc, char **argv ) | |||
28 | 28 | ||
29 | Bu::FString sOpt; | 29 | Bu::FString sOpt; |
30 | int iCount = argc-j; | 30 | int iCount = argc-j; |
31 | Bu::FString sExtraParam; | ||
31 | if( argv[j][iEPos] == '=' ) | 32 | if( argv[j][iEPos] == '=' ) |
32 | { | 33 | { |
33 | sOpt.set( argv[j]+2, iEPos-2 ); | 34 | sOpt.set( argv[j]+2, iEPos-2 ); |
34 | iCount++; | 35 | iCount++; |
36 | sExtraParam.set( argv[j]+iEPos+1 ); | ||
35 | } | 37 | } |
36 | else | 38 | else |
37 | { | 39 | { |
38 | sOpt.set( argv[j]+2 ); | 40 | sOpt.set( argv[j]+2 ); |
39 | } | 41 | } |
40 | Option *pOpt = hlOption.get( sOpt ); | 42 | Option *pOpt = hlOption.get( sOpt ); |
41 | Bu::StrArray aParams( iCount ); | 43 | if( pOpt->sUsed ) |
42 | aParams.append( sOpt ); | ||
43 | if( argv[j][iEPos] == '=' ) | ||
44 | { | 44 | { |
45 | aParams.append( argv[j]+iEPos+1 ); | 45 | Bu::StrArray aParams( iCount ); |
46 | aParams.append( sOpt ); | ||
47 | if( sExtraParam ) | ||
48 | { | ||
49 | aParams.append( argv[j]+iEPos+1 ); | ||
50 | } | ||
51 | for( int k = j+1; k < argc; k++ ) | ||
52 | { | ||
53 | aParams.append( argv[k] ); | ||
54 | } | ||
55 | j += pOpt->sUsed( aParams ); | ||
46 | } | 56 | } |
47 | for( int k = j+1; k < argc; k++ ) | 57 | else if( pOpt->pProxy ) |
48 | { | 58 | { |
49 | aParams.append( argv[k] ); | 59 | if( pOpt->sOverride ) |
60 | { | ||
61 | pOpt->pProxy->setValue( pOpt->sOverride ); | ||
62 | } | ||
63 | else if( sExtraParam ) | ||
64 | { | ||
65 | pOpt->pProxy->setValue( sExtraParam ); | ||
66 | } | ||
67 | else if( argv[j+1] != '\0' ) | ||
68 | { | ||
69 | pOpt->pProxy->setValue( argv[j+1] ); | ||
70 | j++; | ||
71 | } | ||
50 | } | 72 | } |
51 | if( pOpt->sUsed ) | ||
52 | j += pOpt->sUsed( aParams ); | ||
53 | } | 73 | } |
54 | else | 74 | else |
55 | { | 75 | { |
@@ -57,26 +77,45 @@ void Bu::OptParser::parse( int argc, char **argv ) | |||
57 | for( iCPos = 1; argv[j][iCPos] != '\0'; iCPos++ ) | 77 | for( iCPos = 1; argv[j][iCPos] != '\0'; iCPos++ ) |
58 | { | 78 | { |
59 | Option *pOpt = hsOption.get( argv[j][iCPos] ); | 79 | Option *pOpt = hsOption.get( argv[j][iCPos] ); |
60 | Bu::StrArray aParams( argc-j+1 ); | ||
61 | char buf[2] = {argv[j][iCPos], '\0'}; | 80 | char buf[2] = {argv[j][iCPos], '\0'}; |
62 | aParams.append( buf ); | ||
63 | if( pOpt->bShortHasParams ) | 81 | if( pOpt->bShortHasParams ) |
64 | { | 82 | { |
65 | if( argv[j][iCPos+1] != '\0' ) | ||
66 | aParams.append( argv[j]+iCPos+1 ); | ||
67 | for( int k = j+1; k < argc; k++ ) | ||
68 | { | ||
69 | aParams.append( argv[k] ); | ||
70 | } | ||
71 | if( pOpt->sUsed ) | 83 | if( pOpt->sUsed ) |
72 | { | 84 | { |
85 | Bu::StrArray aParams( argc-j+1 ); | ||
86 | aParams.append( buf ); | ||
87 | if( argv[j][iCPos+1] != '\0' ) | ||
88 | aParams.append( argv[j]+iCPos+1 ); | ||
89 | for( int k = j+1; k < argc; k++ ) | ||
90 | { | ||
91 | aParams.append( argv[k] ); | ||
92 | } | ||
73 | j += pOpt->sUsed( aParams ); | 93 | j += pOpt->sUsed( aParams ); |
94 | break; | ||
95 | } | ||
96 | else if( pOpt->pProxy ) | ||
97 | { | ||
98 | if( pOpt->sOverride ) | ||
99 | { | ||
100 | pOpt->pProxy->setValue( pOpt->sOverride ); | ||
101 | } | ||
102 | else if( argv[j][iCPos+1] != '\0' ) | ||
103 | { | ||
104 | pOpt->pProxy->setValue( | ||
105 | argv[j]+iCPos+1 | ||
106 | ); | ||
107 | break; | ||
108 | } | ||
74 | } | 109 | } |
75 | break; | ||
76 | } | 110 | } |
77 | else | 111 | else |
78 | { | 112 | { |
79 | pOpt->sUsed( aParams ); | 113 | if( pOpt->sUsed ) |
114 | { | ||
115 | Bu::StrArray aParam( 1 ); | ||
116 | aParam.append( buf ); | ||
117 | pOpt->sUsed( aParam ); | ||
118 | } | ||
80 | } | 119 | } |
81 | } | 120 | } |
82 | } | 121 | } |
@@ -247,16 +286,44 @@ Bu::FString Bu::OptParser::format( const Bu::FString &sIn, int iWidth, | |||
247 | 286 | ||
248 | 287 | ||
249 | // | 288 | // |
289 | // Code for Bu::OptParser::_ValueProxy | ||
290 | // | ||
291 | |||
292 | Bu::OptParser::_ValueProxy::_ValueProxy() | ||
293 | { | ||
294 | } | ||
295 | |||
296 | Bu::OptParser::_ValueProxy::~_ValueProxy() | ||
297 | { | ||
298 | } | ||
299 | |||
300 | // | ||
250 | // Code for Bu::OptParser::Option | 301 | // Code for Bu::OptParser::Option |
251 | // | 302 | // |
252 | 303 | ||
253 | Bu::OptParser::Option::Option() : | 304 | Bu::OptParser::Option::Option() : |
254 | cOpt( '\0' ), | 305 | cOpt( '\0' ), |
255 | bShortHasParams( false ) | 306 | bShortHasParams( false ), |
307 | pProxy( NULL ) | ||
308 | { | ||
309 | } | ||
310 | |||
311 | Bu::OptParser::Option::Option( const Option &rSrc ) : | ||
312 | cOpt( rSrc.cOpt ), | ||
313 | sOpt( rSrc.sOpt ), | ||
314 | sHelp( rSrc.sHelp ), | ||
315 | sUsed( rSrc.sUsed ), | ||
316 | bShortHasParams( rSrc.bShortHasParams ), | ||
317 | pProxy( NULL ), | ||
318 | sOverride( rSrc.sOverride ) | ||
256 | { | 319 | { |
320 | if( rSrc.pProxy ) | ||
321 | pProxy = rSrc.pProxy->clone(); | ||
257 | } | 322 | } |
258 | 323 | ||
259 | Bu::OptParser::Option::~Option() | 324 | Bu::OptParser::Option::~Option() |
260 | { | 325 | { |
326 | delete pProxy; | ||
327 | pProxy = NULL; | ||
261 | } | 328 | } |
262 | 329 | ||
diff --git a/src/optparser.h b/src/optparser.h index ed32e45..acfb35d 100644 --- a/src/optparser.h +++ b/src/optparser.h | |||
@@ -6,6 +6,8 @@ | |||
6 | #include "bu/hash.h" | 6 | #include "bu/hash.h" |
7 | #include "bu/signals.h" | 7 | #include "bu/signals.h" |
8 | #include "bu/array.h" | 8 | #include "bu/array.h" |
9 | #include "bu/membuf.h" | ||
10 | #include "bu/formatter.h" | ||
9 | 11 | ||
10 | namespace Bu | 12 | namespace Bu |
11 | { | 13 | { |
@@ -13,11 +15,51 @@ namespace Bu | |||
13 | class OptParser | 15 | class OptParser |
14 | { | 16 | { |
15 | public: | 17 | public: |
18 | class _ValueProxy | ||
19 | { | ||
20 | public: | ||
21 | _ValueProxy(); | ||
22 | virtual ~_ValueProxy(); | ||
23 | |||
24 | virtual void setValue( const Bu::FString & )=0; | ||
25 | virtual _ValueProxy *clone()=0; | ||
26 | }; | ||
27 | |||
28 | template<typename ptype> | ||
29 | class ValueProxy : public _ValueProxy | ||
30 | { | ||
31 | public: | ||
32 | ValueProxy( ptype &v ) : | ||
33 | v( v ) | ||
34 | { | ||
35 | } | ||
36 | |||
37 | virtual ~ValueProxy() | ||
38 | { | ||
39 | } | ||
40 | |||
41 | virtual void setValue( const Bu::FString &sVal ) | ||
42 | { | ||
43 | Bu::MemBuf mb( sVal ); | ||
44 | Bu::Formatter f( mb ); | ||
45 | f >> v; | ||
46 | } | ||
47 | |||
48 | virtual _ValueProxy *clone() | ||
49 | { | ||
50 | return new ValueProxy<ptype>( v ); | ||
51 | } | ||
52 | |||
53 | private: | ||
54 | ptype &v; | ||
55 | }; | ||
56 | |||
16 | typedef Signal1<int, StrArray> OptionSignal; | 57 | typedef Signal1<int, StrArray> OptionSignal; |
17 | class Option | 58 | class Option |
18 | { | 59 | { |
19 | public: | 60 | public: |
20 | Option(); | 61 | Option(); |
62 | Option( const Option &rSrc ); | ||
21 | virtual ~Option(); | 63 | virtual ~Option(); |
22 | 64 | ||
23 | char cOpt; | 65 | char cOpt; |
@@ -25,6 +67,8 @@ namespace Bu | |||
25 | Bu::FString sHelp; | 67 | Bu::FString sHelp; |
26 | OptionSignal sUsed; | 68 | OptionSignal sUsed; |
27 | bool bShortHasParams; | 69 | bool bShortHasParams; |
70 | _ValueProxy *pProxy; | ||
71 | Bu::FString sOverride; | ||
28 | }; | 72 | }; |
29 | 73 | ||
30 | public: | 74 | public: |
@@ -34,6 +78,21 @@ namespace Bu | |||
34 | void parse( int argc, char **argv ); | 78 | void parse( int argc, char **argv ); |
35 | 79 | ||
36 | void addOption( const Option &opt ); | 80 | void addOption( const Option &opt ); |
81 | |||
82 | template<typename vtype> | ||
83 | void addOption( char cOpt, const Bu::FString &sOpt, vtype &var, | ||
84 | const Bu::FString &sHelp="", const Bu::FString &sOverride="" ) | ||
85 | { | ||
86 | Option o; | ||
87 | o.cOpt = cOpt; | ||
88 | o.sOpt = sOpt; | ||
89 | o.pProxy = new ValueProxy<vtype>( var ); | ||
90 | o.bShortHasParams = true; | ||
91 | o.sHelp = sHelp; | ||
92 | o.sOverride = sOverride; | ||
93 | addOption( o ); | ||
94 | } | ||
95 | |||
37 | void addHelpOption( char c, const Bu::FString &s, const Bu::FString &sHelp ); | 96 | void addHelpOption( char c, const Bu::FString &s, const Bu::FString &sHelp ); |
38 | 97 | ||
39 | int optHelp( StrArray aParams ); | 98 | int optHelp( StrArray aParams ); |
diff --git a/src/signals.h b/src/signals.h index 075e5bf..975f6af 100644 --- a/src/signals.h +++ b/src/signals.h | |||
@@ -76,7 +76,7 @@ namespace Bu | |||
76 | Signal0() : pCb( NULL ) { } | 76 | Signal0() : pCb( NULL ) { } |
77 | Signal0( _Slot0<ret> *pCb ) : pCb( pCb ) { } | 77 | Signal0( _Slot0<ret> *pCb ) : pCb( pCb ) { } |
78 | Signal0( const Signal0<ret> &rSrc ) : | 78 | Signal0( const Signal0<ret> &rSrc ) : |
79 | pCb( rSrc.pCb->clone() ) { } | 79 | pCb( (rSrc.pCb)?(rSrc.pCb->clone()):(NULL) ) { } |
80 | 80 | ||
81 | virtual ~Signal0() { delete pCb; pCb = NULL; } | 81 | virtual ~Signal0() { delete pCb; pCb = NULL; } |
82 | 82 | ||
@@ -185,7 +185,7 @@ namespace Bu | |||
185 | Signal1() : pCb( NULL ) { } | 185 | Signal1() : pCb( NULL ) { } |
186 | Signal1( _Slot1<ret, p1t> *pCb ) : pCb( pCb ) { } | 186 | Signal1( _Slot1<ret, p1t> *pCb ) : pCb( pCb ) { } |
187 | Signal1( const Signal1<ret, p1t> &rSrc ) : | 187 | Signal1( const Signal1<ret, p1t> &rSrc ) : |
188 | pCb( rSrc.pCb->clone() ) { } | 188 | pCb( (rSrc.pCb)?(rSrc.pCb->clone()):(NULL) ) { } |
189 | 189 | ||
190 | virtual ~Signal1() { delete pCb; pCb = NULL; } | 190 | virtual ~Signal1() { delete pCb; pCb = NULL; } |
191 | 191 | ||
@@ -294,7 +294,7 @@ namespace Bu | |||
294 | Signal2() : pCb( NULL ) { } | 294 | Signal2() : pCb( NULL ) { } |
295 | Signal2( _Slot2<ret, p1t, p2t> *pCb ) : pCb( pCb ) { } | 295 | Signal2( _Slot2<ret, p1t, p2t> *pCb ) : pCb( pCb ) { } |
296 | Signal2( const Signal2<ret, p1t, p2t> &rSrc ) : | 296 | Signal2( const Signal2<ret, p1t, p2t> &rSrc ) : |
297 | pCb( rSrc.pCb->clone() ) { } | 297 | pCb( (rSrc.pCb)?(rSrc.pCb->clone()):(NULL) ) { } |
298 | 298 | ||
299 | virtual ~Signal2() { delete pCb; pCb = NULL; } | 299 | virtual ~Signal2() { delete pCb; pCb = NULL; } |
300 | 300 | ||
@@ -403,7 +403,7 @@ namespace Bu | |||
403 | Signal3() : pCb( NULL ) { } | 403 | Signal3() : pCb( NULL ) { } |
404 | Signal3( _Slot3<ret, p1t, p2t, p3t> *pCb ) : pCb( pCb ) { } | 404 | Signal3( _Slot3<ret, p1t, p2t, p3t> *pCb ) : pCb( pCb ) { } |
405 | Signal3( const Signal3<ret, p1t, p2t, p3t> &rSrc ) : | 405 | Signal3( const Signal3<ret, p1t, p2t, p3t> &rSrc ) : |
406 | pCb( rSrc.pCb->clone() ) { } | 406 | pCb( (rSrc.pCb)?(rSrc.pCb->clone()):(NULL) ) { } |
407 | 407 | ||
408 | virtual ~Signal3() { delete pCb; pCb = NULL; } | 408 | virtual ~Signal3() { delete pCb; pCb = NULL; } |
409 | 409 | ||
@@ -512,7 +512,7 @@ namespace Bu | |||
512 | Signal4() : pCb( NULL ) { } | 512 | Signal4() : pCb( NULL ) { } |
513 | Signal4( _Slot4<ret, p1t, p2t, p3t, p4t> *pCb ) : pCb( pCb ) { } | 513 | Signal4( _Slot4<ret, p1t, p2t, p3t, p4t> *pCb ) : pCb( pCb ) { } |
514 | Signal4( const Signal4<ret, p1t, p2t, p3t, p4t> &rSrc ) : | 514 | Signal4( const Signal4<ret, p1t, p2t, p3t, p4t> &rSrc ) : |
515 | pCb( rSrc.pCb->clone() ) { } | 515 | pCb( (rSrc.pCb)?(rSrc.pCb->clone()):(NULL) ) { } |
516 | 516 | ||
517 | virtual ~Signal4() { delete pCb; pCb = NULL; } | 517 | virtual ~Signal4() { delete pCb; pCb = NULL; } |
518 | 518 | ||
@@ -621,7 +621,7 @@ namespace Bu | |||
621 | Signal5() : pCb( NULL ) { } | 621 | Signal5() : pCb( NULL ) { } |
622 | Signal5( _Slot5<ret, p1t, p2t, p3t, p4t, p5t> *pCb ) : pCb( pCb ) { } | 622 | Signal5( _Slot5<ret, p1t, p2t, p3t, p4t, p5t> *pCb ) : pCb( pCb ) { } |
623 | Signal5( const Signal5<ret, p1t, p2t, p3t, p4t, p5t> &rSrc ) : | 623 | Signal5( const Signal5<ret, p1t, p2t, p3t, p4t, p5t> &rSrc ) : |
624 | pCb( rSrc.pCb->clone() ) { } | 624 | pCb( (rSrc.pCb)?(rSrc.pCb->clone()):(NULL) ) { } |
625 | 625 | ||
626 | virtual ~Signal5() { delete pCb; pCb = NULL; } | 626 | virtual ~Signal5() { delete pCb; pCb = NULL; } |
627 | 627 | ||
diff --git a/src/tests/optparser.cpp b/src/tests/optparser.cpp index ee2ea58..5cf82bd 100644 --- a/src/tests/optparser.cpp +++ b/src/tests/optparser.cpp | |||
@@ -23,6 +23,8 @@ public: | |||
23 | o2.bShortHasParams = false; | 23 | o2.bShortHasParams = false; |
24 | o2.sHelp = "This is the second test parameter. It does not take parameters. However, I do want to make this part much longer to see how it looks when you add way too much text to one of these things. It can't really be that bad, right?"; | 24 | o2.sHelp = "This is the second test parameter. It does not take parameters. However, I do want to make this part much longer to see how it looks when you add way too much text to one of these things. It can't really be that bad, right?"; |
25 | addOption( o2 ); | 25 | addOption( o2 ); |
26 | |||
27 | addOption( 's', "str", sVar, "Set a variable, see what it does.", "bob!"); | ||
26 | 28 | ||
27 | addHelpOption('h', "help", "This help."); | 29 | addHelpOption('h', "help", "This help."); |
28 | } | 30 | } |
@@ -35,6 +37,7 @@ public: | |||
35 | } | 37 | } |
36 | 38 | ||
37 | int iBob; | 39 | int iBob; |
40 | Bu::FString sVar; | ||
38 | }; | 41 | }; |
39 | 42 | ||
40 | int main( int argc, char *argv[] ) | 43 | int main( int argc, char *argv[] ) |
@@ -42,5 +45,7 @@ int main( int argc, char *argv[] ) | |||
42 | Opts o; | 45 | Opts o; |
43 | 46 | ||
44 | o.parse( argc, argv ); | 47 | o.parse( argc, argv ); |
48 | |||
49 | sio << "sVar = \"" << o.sVar << "\"" << sio.nl; | ||
45 | } | 50 | } |
46 | 51 | ||