diff options
| author | Mike Buland <eichlan@xagasoft.com> | 2009-12-16 23:54:13 +0000 |
|---|---|---|
| committer | Mike Buland <eichlan@xagasoft.com> | 2009-12-16 23:54:13 +0000 |
| commit | 0d3d73fb0cacd3d1cf7eb8b83ba87f8b740b871a (patch) | |
| tree | 5e5933681454276d73ceb4ce18719244c9c76d18 /src/optparser.cpp | |
| parent | afac5804b069e5eb76c799e9edd2eaeff0d99b94 (diff) | |
| download | libbu++-0d3d73fb0cacd3d1cf7eb8b83ba87f8b740b871a.tar.gz libbu++-0d3d73fb0cacd3d1cf7eb8b83ba87f8b740b871a.tar.bz2 libbu++-0d3d73fb0cacd3d1cf7eb8b83ba87f8b740b871a.tar.xz libbu++-0d3d73fb0cacd3d1cf7eb8b83ba87f8b740b871a.zip | |
Signals is even safer and works even better. Also, OptParser is nearly done.
Now I just have to come up with a way to modify data that you already have,
that sure was a nice feature of the old one, even if it was implemented in a
silly way.
Diffstat (limited to 'src/optparser.cpp')
| -rw-r--r-- | src/optparser.cpp | 225 |
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" | ||
| 3 | using namespace Bu; | ||
| 4 | |||
| 5 | #include <stdlib.h> | ||
| 2 | 6 | ||
| 3 | Bu::OptParser::OptParser() | 7 | Bu::OptParser::OptParser() |
| 4 | { | 8 | { |
| @@ -8,6 +12,81 @@ Bu::OptParser::~OptParser() | |||
| 8 | { | 12 | { |
| 9 | } | 13 | } |
| 10 | 14 | ||
| 15 | void 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 | |||
| 11 | void Bu::OptParser::addOption( const Option &opt ) | 90 | void 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 | ||
| 99 | void 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 | |||
| 110 | int 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 | ||
| 21 | Bu::FString Bu::OptParser::format( const Bu::FString &sIn, int iWidth, | 160 | Bu::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 | ||
| 32 | Bu::OptParser::Option::Option() | 253 | Bu::OptParser::Option::Option() : |
| 254 | cOpt( '\0' ), | ||
| 255 | bShortHasParams( false ) | ||
| 33 | { | 256 | { |
| 34 | } | 257 | } |
| 35 | 258 | ||
