00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <cxxtls/strtool.h>
00027 #include <stdlib.h>
00028 #include <stdio.h>
00029
00034
00035 using namespace std;
00036
00037 namespace cxxtls
00038 {
00039
00040
00041 string
00042 StrTool::
00043 expand_tabs(char const *s, bool *non_printable_chars, char replacement )
00044 {
00045 string rv;
00046
00047 int count=0;
00048
00049 char c;
00050
00051 while(0 != (c = *s++) )
00052 {
00053 if(c == '\t')
00054 {
00055
00056
00057
00058
00059
00060 int next_tab_stop = count + 8 - count % 8;
00061
00062 while(count != next_tab_stop)
00063 {
00064 rv += ' ';
00065 ++count;
00066 }
00067
00068 }
00069 else
00070 {
00071 if(c < ' ' || c >= 0x7f )
00072 {
00073 if(non_printable_chars)
00074 *non_printable_chars = true;
00075
00076 if(replacement)
00077 c = replacement;
00078 }
00079
00080 rv += c;
00081 ++count;
00082 }
00083 }
00084
00085 return rv;
00086
00087 }
00088
00089
00090 string
00091 StrTool::
00092 pack_tabs(char const *s, bool stop_after_first_non_blank)
00093
00094 {
00095
00096 string rv;
00097
00098 int output=0;
00099 int input=0;
00100
00101 char space=0x20;
00102
00103 char c;
00104
00105 for(;;)
00106 {
00107 c = *s++;
00108
00109 if(c == space)
00110 {
00111 ++input;
00112
00113 }
00114 else
00115 if(c == '\t')
00116 {
00117 input >>= 3;
00118 ++input;
00119 input <<= 3;
00120 }
00121 else
00122 {
00123
00124
00125 if( (input - output == 1) &&
00126 (output%8 == 7)
00127 )
00128 {
00129 rv += space;
00130 ++output;
00131 }
00132 else
00133 {
00134
00135 int tout = output >> 3;
00136 int tin = input >> 3;
00137
00138 if(tout != tin)
00139 {
00140 while(tout != tin)
00141 {
00142 rv += '\t';
00143
00144
00145 ++tout;
00146 }
00147
00148 output = tout << 3;
00149
00150 }
00151 }
00152
00153
00154 while(output != input)
00155 {
00156 rv += space;
00157 ++output;
00158 }
00159
00160
00161 if(c == 0)
00162 {
00163 break;
00164 }
00165
00166 rv += c;
00167
00168 ++input;
00169
00170 output = input;
00171
00172
00173
00174 if(stop_after_first_non_blank)
00175 {
00176 rv += s;
00177 return rv;
00178 }
00179
00180 }
00181
00182 }
00183
00184 return rv;
00185 }
00186
00187 void
00188 StrTool::
00189 remove_leading(std::string &s, char space)
00190 {
00191
00192
00193 std::string::iterator scan = s.begin(),
00194 end = s.end();
00195
00196 while(scan != end && *scan == space)
00197 ++scan;
00198
00199 if(scan != s.begin())
00200 s.erase(s.begin(), scan);
00201
00202 }
00203
00204
00205
00206 bool
00207 StrTool::
00208 snatch_file_info(std::string const &s, std::string &outputFile, int &outputLine)
00209 {
00210
00211
00212 size_t rLength = s.size();
00213
00214 if(rLength == 0)
00215 return false;
00216
00217 size_t firstNonBlank = s.find_first_not_of(" \t");
00218
00219 if(firstNonBlank > rLength)
00220 return false;
00221
00222 std::string tmp(s.begin() + firstNonBlank, s.end());
00223
00224 tmp += ' ';
00225
00226 char name[3000];
00227 char numbuff[3000];
00228 int number;
00229
00230 name[0] = 0;
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251 if( 2 == sscanf(tmp.c_str(), "(%[^:]:%d)", name, &number) )
00252 {
00253
00254
00255 }
00256 else
00257 if( 1 == sscanf(tmp.c_str(), "(in %[^):]", name) )
00258 {
00259 number=1;
00260 }
00261 else
00262 if( 2 ==
00263 sscanf(tmp.c_str(), "error: \"%[+-.$#@!`~=a-zA-Z0-9_/\\]\", line %[0-9]",
00264 name,
00265 numbuff
00266 )
00267 )
00268 {
00269
00270 number=atol(numbuff);
00271 }
00272 else
00273 if( 2 ==
00274 sscanf(tmp.c_str(), "warning: \"%[+-.$#@!`~=a-zA-Z0-9_/\\]\", line %[0-9]",
00275 name,
00276 numbuff
00277 )
00278 )
00279 {
00280
00281 number=atol(numbuff);
00282 }
00283 else
00284 if( 2 ==
00285 sscanf(tmp.c_str(), "Error %*[()0-9]: \"%[+-.$#@!`~=a-zA-Z0-9_/\\]\", line %[0-9]",
00286 name,
00287 numbuff
00288 )
00289 )
00290 {
00291 number=atol(numbuff);
00292 }
00293 else
00294 if( 2 ==
00295 sscanf(tmp.c_str(), "# %[0-9] \"%[^\"]\"",
00296 numbuff,
00297 name
00298 )
00299 )
00300 {
00301
00302
00303
00304 number=atol(numbuff);
00305 }
00306 else
00307 if( 2 ==
00308 sscanf(tmp.c_str(), "#line %[0-9] \"%[^\"]\"",
00309 numbuff,
00310 name
00311 )
00312 )
00313 {
00314
00315
00316
00317 number=atol(numbuff);
00318 }
00319 else
00320 if( 2 ==
00321 sscanf(tmp.c_str(), "\"%[+-.$#@!`~=a-zA-Z0-9_/\\]\", line %[0-9]",
00322 name,
00323 numbuff
00324 )
00325 )
00326 {
00327
00328
00329
00330 number = atol(numbuff);
00331 }
00332 else
00333 if( 2 ==
00334 sscanf(tmp.c_str(), "%[^ :]:%d:", name, &number)
00335 )
00336 {
00337
00338
00339
00340 }
00341 else
00342 if( 2 == sscanf(tmp.c_str(), "%s %d", name, &number) )
00343 {
00344
00345
00346
00347 }
00348 else
00349 if( 2 == sscanf(tmp.c_str(), "%[^(](%d)", name, &number) )
00350 {
00351
00352
00353
00354 }
00355 else
00356 if( 1 == sscanf(tmp.c_str(), "\"%[^\"]\"", name) )
00357 {
00358
00359 number=1;
00360
00361 }
00362 else
00363 if( 1 == sscanf(tmp.c_str(), "<%[^>]>", name) )
00364 {
00365 number=1;
00366 }
00367 else
00368 if( 1 == sscanf(tmp.c_str(), "%[^: ]:", name) )
00369 {
00370
00371 number=1;
00372
00373
00374
00375 int l = strlen(name);
00376
00377 while(l)
00378 {
00379 --l;
00380 if(name[l] != ' ')
00381 break;
00382 }
00383
00384 name[l+1] = 0;
00385
00386 #ifdef _MSC_VER
00387
00388 if(l == 0 && tmp[1] == ':' )
00389 {
00390 if( (name[0] >= 'a' && name[0] <= 'z')
00391 || (name[0] >= 'A' && name[0] <= 'Z')
00392 )
00393 {
00394
00395
00396
00397
00398
00399
00400
00401
00402 std::string drive = tmp.substr(0,2);
00403 std::string path = tmp.substr(2,tmp.size()-2);
00404
00405 if(2 == sscanf(path.c_str(), "%[^ :]:%d:", name, &number ) )
00406 {
00407 drive += name;
00408
00409 strcpy(name, drive.c_str());
00410
00411 }
00412 else
00413 {
00414 drive = tmp.substr(0,tmp.size()-1);
00415
00416 strcpy(name, drive.c_str());
00417 }
00418
00419
00420 }
00421 }
00422
00423 #endif
00424
00425
00426 }
00427 else
00428
00429 {
00430
00431
00432 number = 1;
00433 sscanf(tmp.c_str(), "%s", name);
00434
00435 }
00436
00437 outputFile = name;
00438 outputLine = number;
00439
00440 return !outputFile.empty();
00441
00442
00443 }
00444
00445
00446 }