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
00027
00028
00029
00030 #include "w_defines.h"
00031
00032
00033
00034 #define W_SOURCE
00035
00036 #include <w_base.h>
00037 #include <cctype>
00038 #include <iostream>
00039
00040
00041 enum states { start, sgned, leadz,
00042 new_hex, new_oct, new_dec,
00043 is_hex, is_oct, is_dec,
00044 end, error, no_hex, no_state };
00045
00046
00047 enum charclass { zero=0, one=1, two=2, three=3, four=4,
00048 five=5, six=6, seven=7, eight=8,
00049 nine=9, ten=10, eleven=11,
00050 twelve=12, thirteen=13, fourteen=14, fifteen=15,
00051 exx, JJJJ, eofile, white, sign, no_charclass
00052 };
00053
00054 static int equiv[127] = {
00055
00056
00057 JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, white,
00058
00059 JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ,
00060
00061 JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ,
00062
00063 JJJJ, JJJJ, white, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ,
00064
00065 JJJJ, JJJJ, JJJJ, sign, JJJJ, sign, JJJJ, JJJJ, zero, one,
00066
00067 two , three, four, five, six, seven, eight, nine, JJJJ, JJJJ,
00068
00069 JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, ten, eleven, twelve, thirteen, fourteen,
00070
00071 fifteen, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ,
00072
00073 JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, exx, JJJJ,
00074
00075 JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, ten, eleven, twelve,
00076
00077 thirteen, fourteen, fifteen, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ,
00078
00079 JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ,
00080
00081 exx, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ
00082 };
00083
00084 typedef enum states XTABLE[no_charclass][no_state];
00085 static enum states table_unknown[no_charclass][no_state] =
00086 {
00087
00088
00089 { leadz, leadz, leadz, is_hex, is_oct, is_dec, is_hex, is_oct, is_dec, error },
00090
00091 { new_dec,new_dec,new_oct,is_hex, is_oct, is_dec, is_hex, is_oct, is_dec, error},
00092 { new_dec,new_dec,new_oct,is_hex, is_oct, is_dec, is_hex, is_oct, is_dec, error},
00093 { new_dec,new_dec,new_oct,is_hex, is_oct, is_dec, is_hex, is_oct, is_dec, error},
00094 { new_dec,new_dec,new_oct,is_hex, is_oct, is_dec, is_hex, is_oct, is_dec, error},
00095 { new_dec,new_dec,new_oct,is_hex, is_oct, is_dec, is_hex, is_oct, is_dec, error},
00096 { new_dec,new_dec,new_oct,is_hex, is_oct, is_dec, is_hex, is_oct, is_dec, error},
00097 { new_dec,new_dec,new_oct,is_hex, is_oct, is_dec, is_hex, is_oct, is_dec, error},
00098
00099 { new_dec,new_dec,new_dec,is_hex, end, is_dec, is_hex, is_oct, is_dec,error },
00100 { new_dec,new_dec,new_dec,is_hex, end, is_dec, is_hex, is_oct, is_dec,error },
00101
00102 { error,error,new_hex,is_hex, end, end, is_hex, end, end, error },
00103 { error,error,new_hex,is_hex, end, end, is_hex, end, end, error },
00104 { error,error,new_hex,is_hex, end, end, is_hex, end, end, error },
00105 { error,error,new_hex,is_hex, end, end, is_hex, end, end, error },
00106 { error,error,new_hex,is_hex, end, end, is_hex, end, end, error },
00107 { error,error,new_hex,is_hex, end, end, is_hex, end, end, error },
00108
00109 { error, error, new_hex,end, end, end, end, end, end, error },
00110
00111 { error, error, end, no_hex, end, end, end, end, end, error },
00112
00113 { error, error, end, no_hex, end, end, end, end, end, error },
00114
00115 { start, error, end, end, end, end, end, end, end, error },
00116
00117 { sgned, error, end, no_hex, end, end, end, end, end, error },
00118 };
00119
00120 static enum states table_base16[no_charclass][no_state] =
00121 {
00122
00123
00124 { leadz, leadz, leadz, is_hex, error, error, is_hex, error, error, error },
00125
00126 { is_hex,is_hex, is_hex, is_hex, error, error, is_hex, error, error, error },
00127 { is_hex,is_hex, is_hex, is_hex, error, error, is_hex, error, error, error },
00128 { is_hex,is_hex, is_hex, is_hex, error, error, is_hex, error, error, error },
00129 { is_hex,is_hex, is_hex, is_hex, error, error, is_hex, error, error, error },
00130 { is_hex,is_hex, is_hex, is_hex, error, error, is_hex, error, error, error },
00131 { is_hex,is_hex, is_hex, is_hex, error, error, is_hex, error, error, error },
00132 { is_hex,is_hex, is_hex, is_hex, error, error, is_hex, error, error, error },
00133
00134 { is_hex, is_hex, is_hex, is_hex, error,error, is_hex, error, error, error },
00135 { is_hex, is_hex, is_hex, is_hex, error,error, is_hex, error, error, error },
00136
00137 { is_hex, is_hex, is_hex, is_hex, error,error, is_hex, error, error, error },
00138 { is_hex, is_hex, is_hex, is_hex, error,error, is_hex, error, error, error },
00139 { is_hex, is_hex, is_hex, is_hex, error,error, is_hex, error, error, error },
00140 { is_hex, is_hex, is_hex, is_hex, error,error, is_hex, error, error, error },
00141 { is_hex, is_hex, is_hex, is_hex, error,error,is_hex, error, error, error },
00142 { is_hex, is_hex, is_hex, is_hex, error,error,is_hex, error, error, error },
00143
00144 { error, error, new_hex, end, error,error, end, error, error, error },
00145
00146 { error, error, end, no_hex, error,error, end, error, error, error },
00147
00148 { error, error, end, no_hex, error,error, end, error, error, error },
00149
00150 { start, error, end, no_hex, error,error, end, error, error, error },
00151
00152 { sgned, error, end, no_hex, error,error, end, error, error, error },
00153 };
00154
00155 static enum states table_base8[no_charclass][no_state] =
00156 {
00157
00158
00159 { leadz, leadz, leadz, error, error, error, error, is_oct, error, error },
00160
00161 { is_oct,is_oct, is_oct, error, error, error, error, is_oct, error,error },
00162 { is_oct,is_oct, is_oct, error, error, error, error, is_oct, error,error },
00163 { is_oct,is_oct, is_oct, error, error, error, error, is_oct, error,error },
00164 { is_oct,is_oct, is_oct, error, error, error, error, is_oct, error,error },
00165 { is_oct,is_oct, is_oct, error, error, error, error, is_oct, error,error },
00166 { is_oct,is_oct, is_oct, error, error, error, error, is_oct, error,error },
00167 { is_oct,is_oct, is_oct, error, error, error, error, is_oct, error,error },
00168
00169 { end, error, end, error, error, error, error, end, error, error },
00170 { end, error, end, error, error, error, error, end, error, error },
00171
00172 { end, error, end, error, error,error, error, end, error, error },
00173 { end, error, end, error, error,error, error, end, error, error },
00174 { end, error, end, error, error,error, error, end, error, error },
00175 { end, error, end, error, error,error, error, end, error, error },
00176 { end, error, end, error, error,error, error, end, error, error },
00177 { end, error, end, error, error,error, error, end, error, error },
00178
00179 { error, error, new_hex,end, error,error, end, error, error, error },
00180
00181 { error, error, end, error, error,error, error, end, error, error },
00182
00183 { error, error, end, error, error,error, error, end, error, error },
00184
00185 { start, error, end, error, error,error, error, end, error, error },
00186
00187 { sgned, error, end, error, error,error, error, end, error, error },
00188 };
00189
00190 static enum states table_base10[no_charclass][no_state] =
00191 {
00192
00193
00194
00195
00196 { leadz, leadz, leadz, error, error, error, error, is_oct, is_dec, error },
00197
00198 { is_dec,is_dec, is_dec, error, error, error, error, error, is_dec,error },
00199 { is_dec,is_dec, is_dec, error, error, error, error, error, is_dec,error },
00200 { is_dec,is_dec, is_dec, error, error, error, error, error, is_dec,error },
00201 { is_dec,is_dec, is_dec, error, error, error, error, error, is_dec,error },
00202 { is_dec,is_dec, is_dec, error, error, error, error, error, is_dec,error },
00203 { is_dec,is_dec, is_dec, error, error, error, error, error, is_dec,error },
00204 { is_dec,is_dec, is_dec, error, error, error, error, error, is_dec,error },
00205
00206 { is_dec,is_dec, end, error, error, error, error, end, is_dec,error },
00207 { is_dec,is_dec, end, error, error, error, error, end, is_dec,error },
00208
00209 { end, error, end, error, error,error, error, end, error, error },
00210 { end, error, end, error, error,error, error, end, error, error },
00211 { end, error, end, error, error,error, error, end, error, error },
00212 { end, error, end, error, error,error, error, end, error, error },
00213 { end, error, end, error, error,error, error, end, error, error },
00214 { end, error, end, error, error,error, error, end, error, error },
00215
00216 { error, error, new_hex, end, error,error, end, error, error, error },
00217
00218 { error, error, end, error, error,error, error, error, end, error },
00219
00220 { error, error, end, error, error,error, error, error, end, error },
00221
00222 { start, error, end, error, error,error, error, error, end, error },
00223
00224 { sgned, error, end, error, error,error, error, error, end, error },
00225 };
00226
00227
00228
00229
00230
00231 #ifdef __GNUG__
00232 #define IOS_BACK(stream,ch) (void) stream.unget()
00233 #else
00234 #define IOS_BACK(stream,ch) (void) stream.seekg(-1, ios::cur)
00235 #endif
00236
00237 #if defined( __GNUG__)
00238 #define IOS_FAIL(stream) stream.setstate(ios::failbit)
00239 #else
00240 #define IOS_FAIL(stream) stream.setstate(ios_base::failbit)
00241 #endif
00242
00243
00244 typedef ios::fmtflags ios_fmtflags;
00245
00246
00247
00248
00249 # define LONGLONGCONSTANT(i) i##LL
00250 # define ULONGLONGCONSTANT(i) i##ULL
00251
00252
00253
00254 w_base_t::uint8_t thresh_hex_unsigned =
00255 ULONGLONGCONSTANT(0xf000000000000000);
00256 w_base_t::uint8_t thresh_hex_signed =
00257 LONGLONGCONSTANT(0xf800000000000000);
00258 w_base_t::uint8_t thresh_dec_unsigned =
00259 ULONGLONGCONSTANT(1844674407370955161) ;
00260 w_base_t::uint8_t thresh_dec_signed =
00261 LONGLONGCONSTANT(922337203685477580);
00262 w_base_t::uint8_t thresh2_dec_unsigned =
00263 ULONGLONGCONSTANT(18446744073709551610) ;
00264 w_base_t::uint8_t thresh2_dec_signed =
00265 LONGLONGCONSTANT(9223372036854775800);
00266 w_base_t::uint8_t thresh_oct_unsigned =
00267 ULONGLONGCONSTANT(0xe000000000000000);
00268 w_base_t::uint8_t thresh_oct_signed =
00269 LONGLONGCONSTANT(0xf000000000000000);
00270
00271
00272
00273
00274
00275 istream &
00276 w_base_t::_scan_uint8(
00277 istream& i,
00278 w_base_t::uint8_t &u8,
00279 bool chew_white,
00280 bool is_signed,
00281 bool& range_err
00282 )
00283 {
00284 w_base_t::uint8_t thresh=0,
00285 thresh2=0 ,
00286 thresh3=0, thresh4=0;
00287 w_base_t::uint8_t value = 0;
00288
00289 bool negate = false;
00290 int e=0;
00291 int base=0;
00292 bool skip_white = true;
00293 states s = start;
00294 streampos tell_start = i.tellg();
00295 int chewamt = chew_white? 1 : 0;
00296 XTABLE *table=0;
00297
00298 range_err = false;
00299 {
00300
00301 ios_fmtflags old = i.flags();
00302 skip_white = ((old & ios::skipws) != 0);
00303 switch(old & ios::basefield) {
00304 case 0:
00305 base = 0;
00306 table = &table_unknown;
00307 break;
00308
00309 case ios::hex:
00310 base = 4;
00311 table = &table_base16;
00312 thresh = is_signed? thresh_hex_signed : thresh_hex_unsigned;
00313 break;
00314
00315 case ios::oct:
00316 base = 3;
00317 table = &table_base8;
00318 thresh = is_signed? thresh_oct_signed : thresh_oct_unsigned;
00319 break;
00320
00321 case ios::dec:
00322 base = 10;
00323 table = &table_base10;
00324 thresh = is_signed? thresh_dec_signed : thresh_dec_unsigned;
00325 thresh2 = is_signed? thresh2_dec_signed : thresh2_dec_unsigned;
00326 thresh3 = is_signed? (negate? 8: 7) : 5;
00327 thresh4 = is_signed? thresh_hex_signed : thresh_hex_unsigned;
00328 break;
00329 default:
00330 W_FATAL(fcINTERNAL);
00331 break;
00332 }
00333 }
00334
00335 int ich;
00336 char ch;
00337 while (s < end) {
00338 ch = 0;
00339
00340 ich = i.get();
00341 if (ich != EOF) {
00342 ch = char(ich);
00343
00344 if(isspace(ch)) {
00345 e = white;
00346 } else {
00347 e = equiv[unsigned(ch)];
00348 }
00349 }
00350 else
00351 e = eofile;
00352
00353
00354
00355
00356
00357 s = (*table)[e][s];
00358
00359 switch(s) {
00360 case start:
00361
00362 if(!skip_white) {
00363 s = end;
00364 }
00365 tell_start += chewamt;
00366 break;
00367
00368 case sgned:
00369 if(ch == '-') {
00370 negate = true;
00371 if(thresh3!=0) thresh3 = is_signed? (negate? 8: 7) : 5;
00372 }
00373 break;
00374
00375 case leadz:
00376
00377
00378
00379
00380 break;
00381
00382 case new_hex:
00383
00384 if(base && (base != 4)) {
00385
00386 IOS_BACK(i, ch);
00387 s = end;
00388 break;
00389 }
00390 w_assert9(base == 0 || base == 4);
00391 if((base == 0) && (e != exx)) {
00392
00393 IOS_BACK(i, ch);
00394 s = end;
00395 break;
00396 }
00397
00398
00399
00400
00401
00402
00403
00404
00405 base = 4;
00406 if(e != exx) {
00407 IOS_BACK(i, ch);
00408 } else {
00409
00410
00411 tell_start = i.tellg();
00412 tell_start -= 1;
00413 }
00414 thresh = is_signed? thresh_hex_signed : thresh_hex_unsigned;
00415 break;
00416
00417 case new_oct:
00418
00419 if(base==0 || base == 3) {
00420
00421 base = 3;
00422 thresh = is_signed? thresh_oct_signed : thresh_oct_unsigned;
00423 } else if(base == 10) {
00424 s = new_dec;
00425 thresh = is_signed? thresh_dec_signed : thresh_dec_unsigned;
00426 thresh2= is_signed?thresh2_dec_signed : thresh2_dec_unsigned;
00427 thresh3 = is_signed? (negate? 8: 7) : 5;
00428 thresh4 = is_signed? thresh_hex_signed : thresh_hex_unsigned;
00429 } else {
00430 w_assert9(base == 4);
00431 s = new_hex;
00432 thresh = is_signed? thresh_hex_signed : thresh_hex_unsigned;
00433 }
00434 IOS_BACK(i, ch);
00435 break;
00436
00437 case new_dec:
00438
00439
00440
00441 if(e == eight || e == nine) {
00442 if(base && base != 10) {
00443
00444 IOS_BACK(i, ch);
00445 s = end;
00446 break;
00447 }
00448 }
00449 if(base==0 || base == 10) {
00450
00451 base = 10;
00452 thresh = is_signed? thresh_dec_signed : thresh_dec_unsigned;
00453 thresh2= is_signed?thresh2_dec_signed : thresh2_dec_unsigned;
00454 thresh3 = is_signed? (negate? 8: 7) : 5;
00455 thresh4 = is_signed? thresh_hex_signed : thresh_hex_unsigned;
00456 } else if(base == 3) {
00457 s = new_oct;
00458 thresh = is_signed? thresh_oct_signed : thresh_oct_unsigned;
00459 } else {
00460 w_assert9(base == 4);
00461 thresh = is_signed? thresh_hex_signed : thresh_hex_unsigned;
00462 s = new_hex;
00463 }
00464 IOS_BACK(i, ch);
00465 break;
00466
00467 case is_hex:
00468 w_assert9(base == 4);
00469
00470
00471 case is_oct:
00472 if(value & thresh) {
00473 range_err = true;
00474
00475
00476 break;
00477 }
00478
00479 value <<= base;
00480 value += int(e);
00481 break;
00482
00483 case is_dec:
00484 w_assert9(base == 10);
00485 if(value & thresh4) {
00486 if(value > thresh2) {
00487
00488 range_err = true;
00489
00490
00491 break;
00492 }
00493 value *= base;
00494 if((value - thresh2) + unsigned(e) > thresh3) {
00495
00496 range_err = true;
00497
00498
00499 break;
00500 }
00501 } else {
00502
00503 value *= base;
00504 }
00505 value += unsigned(e);
00506 break;
00507
00508 case error:
00509 IOS_FAIL(i);
00510 i.seekg(tell_start);
00511 s = end;
00512 break;
00513
00514 case no_hex:
00515 i.seekg(tell_start);
00516 s = end;
00517 break;
00518
00519 case end:
00520 IOS_BACK(i, ch);
00521 break;
00522
00523 case no_state:
00524 W_FATAL(fcINTERNAL);
00525 break;
00526 }
00527 }
00528 if(range_err) {
00529
00530 u8 = negate ?
00531 ( is_signed? w_base_t::int8_min : w_base_t::uint8_max) :
00532 ( is_signed? w_base_t::int8_max : w_base_t::uint8_max);
00533 IOS_FAIL(i);
00534 } else {
00535 u8 = negate ? (0 - value) : value;
00536 }
00537
00538 return i;
00539 }
00540
00541