aboutsummaryrefslogtreecommitdiff
path: root/src/optparser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/optparser.cpp')
-rw-r--r--src/optparser.cpp225
1 files changed, 224 insertions, 1 deletions
diff --git a/src/optparser.cpp b/src/optparser.cpp
index 2046792..f99dd85 100644
--- a/src/optparser.cpp
+++ b/src/optparser.cpp
@@ -1,4 +1,8 @@
1#include "bu/optparser.h" 1#include "bu/optparser.h"
2#include "bu/sio.h"
3using namespace Bu;
4
5#include <stdlib.h>
2 6
3Bu::OptParser::OptParser() 7Bu::OptParser::OptParser()
4{ 8{
@@ -8,6 +12,81 @@ Bu::OptParser::~OptParser()
8{ 12{
9} 13}
10 14
15void Bu::OptParser::parse( int argc, char **argv )
16{
17 for( int j = 1; j < argc; j++ )
18 {
19 if( argv[j][0] == '-' )
20 {
21 // Now we're on to something, which kind is it?
22 if( argv[j][1] == '-' )
23 {
24 // Long param, cool, that's easy, first search for =
25 int iEPos;
26 for( iEPos = 2; argv[j][iEPos] != '\0' &&
27 argv[j][iEPos] != '='; iEPos++ ) { }
28
29 Bu::FString sOpt;
30 int iCount = argc-j;
31 if( argv[j][iEPos] == '=' )
32 {
33 sOpt.set( argv[j]+2, iEPos-2 );
34 iCount++;
35 }
36 else
37 {
38 sOpt.set( argv[j]+2 );
39 }
40 Option *pOpt = hlOption.get( sOpt );
41 Bu::StrArray aParams( iCount );
42 aParams.append( sOpt );
43 if( argv[j][iEPos] == '=' )
44 {
45 aParams.append( argv[j]+iEPos+1 );
46 }
47 for( int k = j+1; k < argc; k++ )
48 {
49 aParams.append( argv[k] );
50 }
51 if( pOpt->sUsed )
52 j += pOpt->sUsed( aParams );
53 }
54 else
55 {
56 int iCPos;
57 for( iCPos = 1; argv[j][iCPos] != '\0'; iCPos++ )
58 {
59 Option *pOpt = hsOption.get( argv[j][iCPos] );
60 Bu::StrArray aParams( argc-j+1 );
61 char buf[2] = {argv[j][iCPos], '\0'};
62 aParams.append( buf );
63 if( pOpt->bShortHasParams )
64 {
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 )
72 {
73 j += pOpt->sUsed( aParams );
74 }
75 break;
76 }
77 else
78 {
79 pOpt->sUsed( aParams );
80 }
81 }
82 }
83 }
84 else
85 {
86 }
87 }
88}
89
11void Bu::OptParser::addOption( const Option &opt ) 90void Bu::OptParser::addOption( const Option &opt )
12{ 91{
13 lOption.append( opt ); 92 lOption.append( opt );
@@ -15,13 +94,155 @@ void Bu::OptParser::addOption( const Option &opt )
15 hsOption.insert( opt.cOpt, &lOption.last() ); 94 hsOption.insert( opt.cOpt, &lOption.last() );
16 if( opt.sOpt ) 95 if( opt.sOpt )
17 hlOption.insert( opt.sOpt, &lOption.last() ); 96 hlOption.insert( opt.sOpt, &lOption.last() );
97}
18 98
99void Bu::OptParser::addHelpOption( char c, const Bu::FString &s, const Bu::FString &sHelp )
100{
101 Option o;
102 o.sUsed = slot( this, &OptParser::optHelp );
103 o.cOpt = c;
104 o.sOpt = s;
105 o.sHelp = sHelp;
106 o.bShortHasParams = false;
107 addOption( o );
108}
109
110int Bu::OptParser::optHelp( StrArray aParams )
111{
112 bool bHasShort = false;
113 int iMaxWidth = 0;
114 int iScrWidth = 80;
115 char *env = getenv("COLUMNS");
116 if( env )
117 iScrWidth = strtol( env, NULL, 10 );
118 for( OptionList::iterator i = lOption.begin(); i; i++ )
119 {
120 if( (*i).cOpt != '\0' )
121 bHasShort = true;
122 if( (*i).sOpt && iMaxWidth < (*i).sOpt.getSize() )
123 iMaxWidth = (*i).sOpt.getSize();
124 }
125 int iIndent = 4;
126 if( bHasShort )
127 iIndent += 4;
128 if( iMaxWidth > 0 )
129 iIndent += 4 + iMaxWidth;
130 for( OptionList::iterator i = lOption.begin(); i; i++ )
131 {
132 sio << " ";
133 if( bHasShort )
134 {
135 if( (*i).cOpt == '\0' )
136 sio << " ";
137 else
138 sio << "-" << (*i).cOpt;
139 sio << " ";
140 }
141 if( iMaxWidth > 0 )
142 {
143 if( (*i).sOpt )
144 {
145 sio << "--" << Fmt(iMaxWidth, Fmt::Left) << (*i).sOpt;
146 }
147 else
148 {
149 sio << " " << Fmt(iMaxWidth) << "";
150 }
151 sio << " ";
152 }
153 sio << format( (*i).sHelp, iScrWidth-iIndent-1, iIndent );
154 sio << sio.nl;
155 }
156 exit( 0 );
157 return 0;
19} 158}
20 159
21Bu::FString Bu::OptParser::format( const Bu::FString &sIn, int iWidth, 160Bu::FString Bu::OptParser::format( const Bu::FString &sIn, int iWidth,
22 int iIndent ) 161 int iIndent )
23{ 162{
163 Bu::FString sOut;
164 Bu::FString sIndent;
165 for( int j = 0; j < iIndent; j++ )
166 sIndent.append(" ", 1);
167 bool bFirst = true;
168 int iSpaceCount = 0;
169 bool bSpace = false;
170 int iPrevLineLen;
171 int iLineLen = 0;
172 char c;
173 Bu::FString::const_iterator iLastSpace, iStart;
174 for( Bu::FString::const_iterator i = iLastSpace = iStart = sIn.begin(); i; i++ )
175 {
176 c = *i;
177 if( *i == ' ' )
178 {
179 if( bSpace == false )
180 {
181 iLastSpace = i;
182 iSpaceCount++;
183 bSpace = true;
184 iPrevLineLen = iLineLen;
185 }
186 }
187 else
188 {
189 bSpace = false;
190 }
191 iLineLen++;
24 192
193 if( iLineLen >= iWidth )
194 {
195 iSpaceCount--;
196 if( bFirst == true )
197 bFirst = false;
198 else
199 sOut += sIndent;
200 int iExtraSpaces = iWidth-iPrevLineLen;
201 bSpace = false;
202 float fFill = 0.0;
203 int iSubSpaceCount = 0;
204 float fAdd = ((float)iExtraSpaces/(float)iSpaceCount);
205 for( Bu::FString::const_iterator k = iStart; k != iLastSpace; k++ )
206 {
207 sOut += *k;
208 if( *k == ' ' )
209 {
210 if( bSpace == false && iExtraSpaces > 0 )
211 {
212 bSpace = true;
213 fFill += fAdd;
214 iSubSpaceCount++;
215 for( int sp = 0; sp < (int)(fFill); sp++ )
216 {
217 sOut += ' ';
218 iExtraSpaces--;
219 }
220 fFill -= (int)fFill;
221 if( iSubSpaceCount == iSpaceCount && iExtraSpaces > 0 )
222 {
223 for(; iExtraSpaces > 0; iExtraSpaces-- )
224 {
225 sOut += ' ';
226 }
227 }
228 }
229 }
230 else
231 bSpace = false;
232 }
233 //sOut.append( iStart, iLastSpace );
234 sOut.append("\n");
235 for(; iLastSpace && *iLastSpace == ' '; iLastSpace++ ) { }
236 iStart = i = iLastSpace;
237 bSpace = false;
238 iLineLen = 1;
239 iSpaceCount = 0;
240 }
241 }
242 if( !bFirst )
243 sOut += sIndent;
244 sOut.append( iStart );
245 return sOut;
25} 246}
26 247
27 248
@@ -29,7 +250,9 @@ Bu::FString Bu::OptParser::format( const Bu::FString &sIn, int iWidth,
29// Code for Bu::OptParser::Option 250// Code for Bu::OptParser::Option
30// 251//
31 252
32Bu::OptParser::Option::Option() 253Bu::OptParser::Option::Option() :
254 cOpt( '\0' ),
255 bShortHasParams( false )
33{ 256{
34} 257}
35 258