aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Buland <eichlan@xagasoft.com>2009-12-18 08:59:16 +0000
committerMike Buland <eichlan@xagasoft.com>2009-12-18 08:59:16 +0000
commit146930268a695dcc0432599d625ec3eb7e74025e (patch)
treea944d13981ed055b337757953014ed1e2d45e19c
parent0d3d73fb0cacd3d1cf7eb8b83ba87f8b740b871a (diff)
downloadlibbu++-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.
-rw-r--r--src/formatter.cpp172
-rw-r--r--src/formatter.h54
-rw-r--r--src/optparser.cpp105
-rw-r--r--src/optparser.h59
-rw-r--r--src/signals.h12
-rw-r--r--src/tests/optparser.cpp5
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
12Bu::Formatter::Formatter( Stream &rOut ) : 12Bu::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
23void Bu::Formatter::write( const Bu::FString &sStr ) 23void Bu::Formatter::write( const Bu::FString &sStr )
24{ 24{
25 rOut.write( sStr ); 25 rStream.write( sStr );
26} 26}
27 27
28void Bu::Formatter::write( const void *sStr, int iLen ) 28void Bu::Formatter::write( const void *sStr, int iLen )
29{ 29{
30 rOut.write( sStr, iLen ); 30 rStream.write( sStr, iLen );
31} 31}
32 32
33void Bu::Formatter::writeAligned( const Bu::FString &sStr ) 33void 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
114Bu::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
114void Bu::Formatter::incIndent() 144void 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
195Bu::Formatter &Bu::operator<<( Bu::Formatter &rOut, const Bu::Formatter::Fmt &f ) 225Bu::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
201Bu::Formatter &Bu::operator<<( Bu::Formatter &rOut, Bu::Formatter::Special s ) 231Bu::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
251Bu::Formatter &Bu::operator<<( Bu::Formatter &f, const char *sStr )
252{
253 f.writeAligned( sStr, strlen( sStr ) );
254 return f;
219} 255}
220 256
221Bu::Formatter &Bu::operator<<( Bu::Formatter &rOut, const char *sStr ) 257Bu::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
227Bu::Formatter &Bu::operator<<( Bu::Formatter &rOut, char *sStr ) 263Bu::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
233Bu::Formatter &Bu::operator<<( Bu::Formatter &rOut, const Bu::FString &sStr ) 269Bu::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
239Bu::Formatter &Bu::operator<<( Bu::Formatter &rOut, signed char c ) 275Bu::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
245Bu::Formatter &Bu::operator<<( Bu::Formatter &rOut, char c ) 281Bu::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
251Bu::Formatter &Bu::operator<<( Bu::Formatter &rOut, unsigned char c ) 287Bu::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
257Bu::Formatter &Bu::operator<<( Bu::Formatter &rOut, signed short i ) 293Bu::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
263Bu::Formatter &Bu::operator<<( Bu::Formatter &rOut, unsigned short i ) 299Bu::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
269Bu::Formatter &Bu::operator<<( Bu::Formatter &rOut, signed int i ) 305Bu::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
275Bu::Formatter &Bu::operator<<( Bu::Formatter &rOut, unsigned int i ) 311Bu::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
281Bu::Formatter &Bu::operator<<( Bu::Formatter &rOut, signed long i ) 317Bu::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
287Bu::Formatter &Bu::operator<<( Bu::Formatter &rOut, unsigned long i ) 323Bu::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
293Bu::Formatter &Bu::operator<<( Bu::Formatter &rOut, signed long long i ) 329Bu::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
299Bu::Formatter &Bu::operator<<( Bu::Formatter &rOut, unsigned long long i ) 335Bu::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
305Bu::Formatter &Bu::operator<<( Bu::Formatter &rOut, float f ) 341Bu::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
311Bu::Formatter &Bu::operator<<( Bu::Formatter &rOut, double f ) 347Bu::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
317Bu::Formatter &Bu::operator<<( Bu::Formatter &rOut, long double f ) 353Bu::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
323Bu::Formatter &Bu::operator<<( Bu::Formatter &rOut, bool b ) 359Bu::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
292Bu::OptParser::_ValueProxy::_ValueProxy()
293{
294}
295
296Bu::OptParser::_ValueProxy::~_ValueProxy()
297{
298}
299
300//
250// Code for Bu::OptParser::Option 301// Code for Bu::OptParser::Option
251// 302//
252 303
253Bu::OptParser::Option::Option() : 304Bu::OptParser::Option::Option() :
254 cOpt( '\0' ), 305 cOpt( '\0' ),
255 bShortHasParams( false ) 306 bShortHasParams( false ),
307 pProxy( NULL )
308{
309}
310
311Bu::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
259Bu::OptParser::Option::~Option() 324Bu::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
10namespace Bu 12namespace 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
40int main( int argc, char *argv[] ) 43int 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