aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Buland <eichlan@xagasoft.com>2009-12-18 15:32:37 +0000
committerMike Buland <eichlan@xagasoft.com>2009-12-18 15:32:37 +0000
commit038815ae3a019ac56fa1c62e18c5861166d3a975 (patch)
tree816352148be5593f43c746062657849212bdc55e
parent146930268a695dcc0432599d625ec3eb7e74025e (diff)
downloadlibbu++-038815ae3a019ac56fa1c62e18c5861166d3a975.tar.gz
libbu++-038815ae3a019ac56fa1c62e18c5861166d3a975.tar.bz2
libbu++-038815ae3a019ac56fa1c62e18c5861166d3a975.tar.xz
libbu++-038815ae3a019ac56fa1c62e18c5861166d3a975.zip
Wow, cool, Bu::Formatter can read all the basic types now, (int, float, bool,
char, etc.) and OptParser totally works. I have one last change to make to it, which is using the return value of signal type options to determine weather or not the option took a parameter at all, especially in the case of short options.
-rw-r--r--src/formatter.cpp103
-rw-r--r--src/formatter.h73
-rw-r--r--src/optparser.cpp57
-rw-r--r--src/optparser.h74
-rw-r--r--src/stdstream.cpp1
-rw-r--r--src/stdstream.h1
-rw-r--r--src/tests/optparser.cpp63
7 files changed, 340 insertions, 32 deletions
diff --git a/src/formatter.cpp b/src/formatter.cpp
index 5ab1b3f..14f70ed 100644
--- a/src/formatter.cpp
+++ b/src/formatter.cpp
@@ -111,6 +111,11 @@ void Bu::Formatter::writeAligned( const char *sStr, int iLen )
111 usedFormat(); 111 usedFormat();
112} 112}
113 113
114void Bu::Formatter::read( void *sStr, int iLen )
115{
116 rStream.read( sStr, iLen );
117}
118
114Bu::FString Bu::Formatter::readToken() 119Bu::FString Bu::Formatter::readToken()
115{ 120{
116 Bu::FString sRet; 121 Bu::FString sRet;
@@ -362,3 +367,101 @@ Bu::Formatter &Bu::operator>>( Bu::Formatter &f, Bu::FString &sStr )
362 return f; 367 return f;
363} 368}
364 369
370Bu::Formatter &Bu::operator>>( Bu::Formatter &f, signed char &c )
371{
372 f.read( &c, 1 );
373 return f;
374}
375
376Bu::Formatter &Bu::operator>>( Bu::Formatter &f, char &c )
377{
378 f.read( &c, 1 );
379 return f;
380}
381
382Bu::Formatter &Bu::operator>>( Bu::Formatter &f, unsigned char &c )
383{
384 f.read( &c, 1 );
385 return f;
386}
387
388Bu::Formatter &Bu::operator>>( Bu::Formatter &f, signed short &i )
389{
390 f.iparse( i, f.readToken() );
391 return f;
392}
393
394Bu::Formatter &Bu::operator>>( Bu::Formatter &f, unsigned short &i )
395{
396 f.uparse( i, f.readToken() );
397 return f;
398}
399
400Bu::Formatter &Bu::operator>>( Bu::Formatter &f, signed int &i )
401{
402 f.iparse( i, f.readToken() );
403 return f;
404}
405
406Bu::Formatter &Bu::operator>>( Bu::Formatter &f, unsigned int &i )
407{
408 f.uparse( i, f.readToken() );
409 return f;
410}
411
412Bu::Formatter &Bu::operator>>( Bu::Formatter &f, signed long &i )
413{
414 f.iparse( i, f.readToken() );
415 return f;
416}
417
418Bu::Formatter &Bu::operator>>( Bu::Formatter &f, unsigned long &i )
419{
420 f.uparse( i, f.readToken() );
421 return f;
422}
423
424Bu::Formatter &Bu::operator>>( Bu::Formatter &f, signed long long &i )
425{
426 f.iparse( i, f.readToken() );
427 return f;
428}
429
430Bu::Formatter &Bu::operator>>( Bu::Formatter &f, unsigned long long &i )
431{
432 f.uparse( i, f.readToken() );
433 return f;
434}
435
436Bu::Formatter &Bu::operator>>( Bu::Formatter &f, float &flt )
437{
438 f.fparse( flt, f.readToken() );
439 return f;
440}
441
442Bu::Formatter &Bu::operator>>( Bu::Formatter &f, double &flt )
443{
444 f.fparse( flt, f.readToken() );
445 return f;
446}
447
448Bu::Formatter &Bu::operator>>( Bu::Formatter &f, long double &flt )
449{
450 f.fparse( flt, f.readToken() );
451 return f;
452}
453
454Bu::Formatter &Bu::operator>>( Bu::Formatter &f, bool &b )
455{
456 Bu::FString sStr = f.readToken();
457 if( !sStr )
458 return f;
459 char c = *sStr.begin();
460 if( c == 'y' || c == 'Y' || c == 't' || c == 'T' )
461 b = true;
462 else if( c == 'n' || c == 'N' || c == 'f' || c == 'F' )
463 b = false;
464
465 return f;
466}
467
diff --git a/src/formatter.h b/src/formatter.h
index aec5c5d..3f51e8e 100644
--- a/src/formatter.h
+++ b/src/formatter.h
@@ -103,6 +103,7 @@ 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 void read( void *sStr, int iLen );
106 Bu::FString readToken(); 107 Bu::FString readToken();
107 108
108 void incIndent(); 109 void incIndent();
@@ -199,6 +200,63 @@ namespace Bu
199 writeAligned( fTmp ); 200 writeAligned( fTmp );
200 usedFormat(); 201 usedFormat();
201 } 202 }
203
204 template<typename type>
205 void iparse( type &i, const Bu::FString &sBuf )
206 {
207 if( !sBuf )
208 return;
209 if( sBuf[0] != '+' && sBuf[0] != '-' &&
210 (sBuf[0] < '0' && sBuf[0] > '9') )
211 return;
212 int j = 1;
213 int iMax = sBuf.getSize();
214 for(; j < iMax && (sBuf[j] >= '0' && sBuf[j] <= '9'); j++ ) { }
215 i = 0;
216 type iPos = 1;
217 for(j--; j >= 0; j-- )
218 {
219 if( sBuf[j] == '+' || sBuf[j] == '-' )
220 continue;
221 i += (sBuf[j]-'0')*iPos;
222 iPos *= fLast.uRadix;
223 }
224 if( sBuf[0] == '-' )
225 i = -i;
226
227 usedFormat();
228 }
229
230 template<typename type>
231 void uparse( type &i, const Bu::FString &sBuf )
232 {
233 if( !sBuf )
234 return;
235 if( sBuf[0] != '+' &&
236 (sBuf[0] < '0' && sBuf[0] > '9') )
237 return;
238 int j = 1;
239 int iMax = sBuf.getSize();
240 for(; j < iMax && (sBuf[j] >= '0' && sBuf[j] <= '9'); j++ ) { }
241 i = 0;
242 type iPos = 1;
243 for(j--; j >= 0; j-- )
244 {
245 if( sBuf[j] == '+' )
246 continue;
247 i += (sBuf[j]-'0')*iPos;
248 iPos *= fLast.uRadix;
249 }
250
251 usedFormat();
252 }
253
254 template<typename type>
255 void fparse( type &f, const Bu::FString &sBuf )
256 {
257 sscanf( sBuf.getStr(), "%f", &f );
258 usedFormat();
259 }
202 260
203 enum Special 261 enum Special
204 { 262 {
@@ -243,6 +301,21 @@ namespace Bu
243 Formatter &operator<<( Formatter &f, bool b ); 301 Formatter &operator<<( Formatter &f, bool b );
244 302
245 Formatter &operator>>( Formatter &f, Bu::FString &sStr ); 303 Formatter &operator>>( Formatter &f, Bu::FString &sStr );
304 Formatter &operator>>( Formatter &f, signed char &c );
305 Formatter &operator>>( Formatter &f, char &c );
306 Formatter &operator>>( Formatter &f, unsigned char &c );
307 Formatter &operator>>( Formatter &f, signed short &i );
308 Formatter &operator>>( Formatter &f, unsigned short &i );
309 Formatter &operator>>( Formatter &f, signed int &i );
310 Formatter &operator>>( Formatter &f, unsigned int &i );
311 Formatter &operator>>( Formatter &f, signed long &i );
312 Formatter &operator>>( Formatter &f, unsigned long &i );
313 Formatter &operator>>( Formatter &f, signed long long &i );
314 Formatter &operator>>( Formatter &f, unsigned long long &i );
315 Formatter &operator>>( Formatter &f, float &flt );
316 Formatter &operator>>( Formatter &f, double &flt );
317 Formatter &operator>>( Formatter &f, long double &flt );
318 Formatter &operator>>( Formatter &f, bool &b );
246 319
247 template<typename type> 320 template<typename type>
248 Formatter &operator<<( Formatter &f, const type *p ) 321 Formatter &operator<<( Formatter &f, const type *p )
diff --git a/src/optparser.cpp b/src/optparser.cpp
index 2a8e64b..d656e12 100644
--- a/src/optparser.cpp
+++ b/src/optparser.cpp
@@ -106,6 +106,14 @@ void Bu::OptParser::parse( int argc, char **argv )
106 ); 106 );
107 break; 107 break;
108 } 108 }
109 else if( argv[j+1] )
110 {
111 pOpt->pProxy->setValue(
112 argv[j+1]
113 );
114 j++;
115 break;
116 }
109 } 117 }
110 } 118 }
111 else 119 else
@@ -135,6 +143,16 @@ void Bu::OptParser::addOption( const Option &opt )
135 hlOption.insert( opt.sOpt, &lOption.last() ); 143 hlOption.insert( opt.sOpt, &lOption.last() );
136} 144}
137 145
146void Bu::OptParser::setOverride( char cOpt, const Bu::FString &sOverride )
147{
148 hsOption.get( cOpt )->sOverride = sOverride;
149}
150
151void Bu::OptParser::setOverride( const Bu::FString &sOpt, const Bu::FString &sOverride )
152{
153 hlOption.get( sOpt )->sOverride = sOverride;
154}
155
138void Bu::OptParser::addHelpOption( char c, const Bu::FString &s, const Bu::FString &sHelp ) 156void Bu::OptParser::addHelpOption( char c, const Bu::FString &s, const Bu::FString &sHelp )
139{ 157{
140 Option o; 158 Option o;
@@ -146,7 +164,19 @@ void Bu::OptParser::addHelpOption( char c, const Bu::FString &s, const Bu::FStri
146 addOption( o ); 164 addOption( o );
147} 165}
148 166
149int Bu::OptParser::optHelp( StrArray aParams ) 167void Bu::OptParser::addHelpBanner( const Bu::FString &sText, bool bFormatted )
168{
169 Banner b;
170 b.sText = sText;
171 b.bFormatted = bFormatted;
172 if( lOption.getSize() > 0 )
173 {
174 for( b.iAfter = lOption.begin(); b.iAfter+1; b.iAfter++ ) { }
175 }
176 lBanner.append( b );
177}
178
179int Bu::OptParser::optHelp( StrArray /*aParams*/ )
150{ 180{
151 bool bHasShort = false; 181 bool bHasShort = false;
152 int iMaxWidth = 0; 182 int iMaxWidth = 0;
@@ -166,6 +196,19 @@ int Bu::OptParser::optHelp( StrArray aParams )
166 iIndent += 4; 196 iIndent += 4;
167 if( iMaxWidth > 0 ) 197 if( iMaxWidth > 0 )
168 iIndent += 4 + iMaxWidth; 198 iIndent += 4 + iMaxWidth;
199
200 BannerList::iterator iBanner;
201 for( iBanner = lBanner.begin(); iBanner; iBanner++ )
202 {
203 if( (*iBanner).iAfter )
204 break;
205
206 if( (*iBanner).bFormatted )
207 sio << format( (*iBanner).sText, iScrWidth-1, 0 );
208 else
209 sio << (*iBanner).sText;
210 sio << sio.nl;
211 }
169 for( OptionList::iterator i = lOption.begin(); i; i++ ) 212 for( OptionList::iterator i = lOption.begin(); i; i++ )
170 { 213 {
171 sio << " "; 214 sio << " ";
@@ -191,6 +234,18 @@ int Bu::OptParser::optHelp( StrArray aParams )
191 } 234 }
192 sio << format( (*i).sHelp, iScrWidth-iIndent-1, iIndent ); 235 sio << format( (*i).sHelp, iScrWidth-iIndent-1, iIndent );
193 sio << sio.nl; 236 sio << sio.nl;
237
238 for( ; iBanner; iBanner++ )
239 {
240 if( (*iBanner).iAfter != i )
241 break;
242
243 if( (*iBanner).bFormatted )
244 sio << format( (*iBanner).sText, iScrWidth-1, 0 );
245 else
246 sio << (*iBanner).sText;
247 sio << sio.nl;
248 }
194 } 249 }
195 exit( 0 ); 250 exit( 0 );
196 return 0; 251 return 0;
diff --git a/src/optparser.h b/src/optparser.h
index acfb35d..425bc90 100644
--- a/src/optparser.h
+++ b/src/optparser.h
@@ -14,7 +14,7 @@ namespace Bu
14 typedef Bu::Array<Bu::FString> StrArray; 14 typedef Bu::Array<Bu::FString> StrArray;
15 class OptParser 15 class OptParser
16 { 16 {
17 public: 17 private:
18 class _ValueProxy 18 class _ValueProxy
19 { 19 {
20 public: 20 public:
@@ -54,6 +54,7 @@ namespace Bu
54 ptype &v; 54 ptype &v;
55 }; 55 };
56 56
57 public:
57 typedef Signal1<int, StrArray> OptionSignal; 58 typedef Signal1<int, StrArray> OptionSignal;
58 class Option 59 class Option
59 { 60 {
@@ -70,6 +71,21 @@ namespace Bu
70 _ValueProxy *pProxy; 71 _ValueProxy *pProxy;
71 Bu::FString sOverride; 72 Bu::FString sOverride;
72 }; 73 };
74
75 private:
76 typedef Bu::List<Option> OptionList;
77 typedef Bu::Hash<char, Option *> ShortOptionHash;
78 typedef Bu::Hash<Bu::FString, Option *> LongOptionHash;
79
80 class Banner
81 {
82 public:
83 Bu::FString sText;
84 bool bFormatted;
85 OptionList::const_iterator iAfter;
86 };
87
88 typedef Bu::List<Banner> BannerList;
73 89
74 public: 90 public:
75 OptParser(); 91 OptParser();
@@ -80,8 +96,8 @@ namespace Bu
80 void addOption( const Option &opt ); 96 void addOption( const Option &opt );
81 97
82 template<typename vtype> 98 template<typename vtype>
83 void addOption( char cOpt, const Bu::FString &sOpt, vtype &var, 99 void addOption( vtype &var, char cOpt, const Bu::FString &sOpt,
84 const Bu::FString &sHelp="", const Bu::FString &sOverride="" ) 100 const Bu::FString &sHelp )
85 { 101 {
86 Option o; 102 Option o;
87 o.cOpt = cOpt; 103 o.cOpt = cOpt;
@@ -89,24 +105,64 @@ namespace Bu
89 o.pProxy = new ValueProxy<vtype>( var ); 105 o.pProxy = new ValueProxy<vtype>( var );
90 o.bShortHasParams = true; 106 o.bShortHasParams = true;
91 o.sHelp = sHelp; 107 o.sHelp = sHelp;
92 o.sOverride = sOverride;
93 addOption( o ); 108 addOption( o );
94 } 109 }
95 110
96 void addHelpOption( char c, const Bu::FString &s, const Bu::FString &sHelp ); 111 template<typename vtype>
112 void addOption( vtype &var, const Bu::FString &sOpt,
113 const Bu::FString &sHelp )
114 {
115 addOption( var, '\0', sOpt, sHelp );
116 }
117
118 template<typename vtype>
119 void addOption( vtype &var, char cOpt, const Bu::FString &sHelp )
120 {
121 addOption( var, cOpt, "", sHelp );
122 }
123
124 void addOption( OptionSignal sUsed, char cOpt, const Bu::FString &sOpt,
125 const Bu::FString &sHelp )
126 {
127 Option o;
128 o.cOpt = cOpt;
129 o.sOpt = sOpt;
130 o.sUsed = sUsed;
131 o.sHelp = sHelp;
132 addOption( o );
133 }
134
135 void addOption( OptionSignal sUsed, const Bu::FString &sOpt,
136 const Bu::FString &sHelp )
137 {
138 addOption( sUsed, '\0', sOpt, sHelp );
139 }
140
141 void addOption( OptionSignal sUsed, char cOpt,
142 const Bu::FString &sHelp )
143 {
144 addOption( sUsed, cOpt, "", sHelp );
145 }
146
147 void setOverride( char cOpt, const Bu::FString &sOverride );
148 void setOverride( const Bu::FString &sOpt,
149 const Bu::FString &sOverride );
150
151// void addOption( char cOpt, const Bu::FString &sOpt,
152
153 void addHelpOption( char c='h', const Bu::FString &s="help",
154 const Bu::FString &sHelp="This help." );
155 void addHelpBanner( const Bu::FString &sText, bool bFormatted=true );
97 156
98 int optHelp( StrArray aParams ); 157 int optHelp( StrArray aParams );
99 158
100 private: 159 private:
101 Bu::FString format( const Bu::FString &sIn, int iWidth, int iIndent ); 160 Bu::FString format( const Bu::FString &sIn, int iWidth, int iIndent );
102 161
103 typedef Bu::List<Option> OptionList;
104 typedef Bu::Hash<char, Option *> ShortOptionHash;
105 typedef Bu::Hash<Bu::FString, Option *> LongOptionHash;
106
107 OptionList lOption; 162 OptionList lOption;
108 ShortOptionHash hsOption; 163 ShortOptionHash hsOption;
109 LongOptionHash hlOption; 164 LongOptionHash hlOption;
165 BannerList lBanner;
110 }; 166 };
111}; 167};
112 168
diff --git a/src/stdstream.cpp b/src/stdstream.cpp
index 05b8ee7..6f9f052 100644
--- a/src/stdstream.cpp
+++ b/src/stdstream.cpp
@@ -5,6 +5,7 @@
5 * terms of the license contained in the file LICENSE. 5 * terms of the license contained in the file LICENSE.
6 */ 6 */
7 7
8#include <stdio.h>
8#include "bu/stdstream.h" 9#include "bu/stdstream.h"
9 10
10Bu::StdStream::StdStream() 11Bu::StdStream::StdStream()
diff --git a/src/stdstream.h b/src/stdstream.h
index 1bde088..6de1e8c 100644
--- a/src/stdstream.h
+++ b/src/stdstream.h
@@ -9,7 +9,6 @@
9#define BU_STD_STREAM_H 9#define BU_STD_STREAM_H
10 10
11#include <stdint.h> 11#include <stdint.h>
12#include <stdio.h>
13#include "stream.h" 12#include "stream.h"
14 13
15namespace Bu 14namespace Bu
diff --git a/src/tests/optparser.cpp b/src/tests/optparser.cpp
index 5cf82bd..f5df7ed 100644
--- a/src/tests/optparser.cpp
+++ b/src/tests/optparser.cpp
@@ -8,35 +8,54 @@ public:
8 Opts() : 8 Opts() :
9 iBob( 542 ) 9 iBob( 542 )
10 { 10 {
11 Option o; 11 addHelpBanner("optparser - Test some option things...");
12 o.sUsed = slot( this, &Opts::cb ); 12
13 o.cOpt = 'x'; 13 addHelpBanner("\nThis section represents options that actually have "
14 o.sOpt = "things"; 14 "callbacks, or in the case of the new system, signals/slots. They "
15 o.bShortHasParams = true; 15 "all take parameters, but if they return 0 then it will be as "
16 o.sHelp = "This is the first test parameter. It calls a function, and takes parameters."; 16 "though they hadn't and the next thing will be processed normally.",
17 addOption( o ); 17 true
18 18 );
19 Option o2; 19 addOption( slot( this, &Opts::yesparam ), 'x', "things",
20 o2.sUsed = slot( this, &Opts::cb ); 20 "This is the first test parameter. It calls a function, and "
21 o2.cOpt = 'y'; 21 "takes a parameter."
22 o2.sOpt = "stuff"; 22 );
23 o2.bShortHasParams = false; 23 addOption( slot( this, &Opts::noparam ), 'y', "stuff",
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 "This is the second test parameter. It does not take "
25 addOption( o2 ); 25 "parameters. However, I do want to make this part much longer to "
26 26 "see how it looks when you add way too much text to one of these "
27 addOption( 's', "str", sVar, "Set a variable, see what it does.", "bob!"); 27 "things. It can't really be that bad, right?"
28 );
29
30 addHelpBanner("\nThis section represents options with no callback or "
31 "signal, but do have a variable to update. They use the Formatter "
32 "system and therefore it's very, very flexible. Any data type "
33 "you can read with a formatter you can set via parameter.",
34 true
35 );
36 addOption( sVar, 's', "str", "Set a variable, see what it does.");
37 addOption( iBob, "bob", "Change iBob to wahtever you want.");
38 addOption( dBob, 'd', "Change dBob to wahtever you want.");
39
40 setOverride("str", "Bob!");
28 41
29 addHelpOption('h', "help", "This help."); 42 addHelpOption();
30 } 43 }
31 44
32 int cb( StrArray aParams ) 45 int yesparam( StrArray aParams )
33 { 46 {
34 sio << "Hey, cb was called, here's a class var: " << iBob << sio.nl; 47 sio << " - yesparam" << aParams << sio.nl;
35 sio << "argv[] = " << aParams << sio.nl;
36 return 1; 48 return 1;
37 } 49 }
38 50
51 int noparam( StrArray aParams )
52 {
53 sio << " - noparam" << aParams << sio.nl;
54 return 0;
55 }
56
39 int iBob; 57 int iBob;
58 float dBob;
40 Bu::FString sVar; 59 Bu::FString sVar;
41}; 60};
42 61
@@ -47,5 +66,7 @@ int main( int argc, char *argv[] )
47 o.parse( argc, argv ); 66 o.parse( argc, argv );
48 67
49 sio << "sVar = \"" << o.sVar << "\"" << sio.nl; 68 sio << "sVar = \"" << o.sVar << "\"" << sio.nl;
69 sio << "iBob = " << o.iBob << sio.nl;
70 sio << "dBob = " << o.dBob << sio.nl;
50} 71}
51 72