00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "unicode/utypes.h"
00020 #include "unicode/uchar.h"
00021
00022 #include "uscanf.h"
00023 #include "uscanf_p.h"
00024 #include "uscanset.h"
00025 #include "unicode/ustdio.h"
00026 #include "ufile.h"
00027 #include "unicode/ustring.h"
00028 #include "locbund.h"
00029 #include "umutex.h"
00030 #include "unicode/unum.h"
00031 #include "unicode/udat.h"
00032
00033 #include <string.h>
00034 #include <stdlib.h>
00035 #include <float.h>
00036 #include <limits.h>
00037
00038 static u_scanf_handler g_u_scanf_handlers [256];
00039 static u_scanf_info g_u_scanf_infos [256];
00040 static UBool g_u_scanf_inited = FALSE;
00041
00042 int32_t
00043 u_fscanf( UFILE *f,
00044 const char *patternSpecification,
00045 ... )
00046 {
00047 va_list ap;
00048 int32_t converted;
00049
00050 va_start(ap, patternSpecification);
00051 converted = u_vfscanf(f, patternSpecification, ap);
00052 va_end(ap);
00053
00054 return converted;
00055 }
00056
00057 int32_t
00058 u_fscanf_u( UFILE *f,
00059 const UChar *patternSpecification,
00060 ... )
00061 {
00062 va_list ap;
00063 int32_t converted;
00064
00065 va_start(ap, patternSpecification);
00066 converted = u_vfscanf_u(f, patternSpecification, ap);
00067 va_end(ap);
00068
00069 return converted;
00070 }
00071
00072 int32_t
00073 u_vfscanf( UFILE *f,
00074 const char *patternSpecification,
00075 va_list ap)
00076 {
00077 int32_t converted;
00078 UChar *pattern;
00079
00080
00081 pattern = ufmt_defaultCPToUnicode(patternSpecification,
00082 strlen(patternSpecification));
00083 if(pattern == 0) {
00084 return 0;
00085 }
00086
00087
00088 converted = u_vfscanf_u(f, pattern, ap);
00089
00090
00091 free(pattern);
00092
00093 return converted;
00094 }
00095
00096 int32_t
00097 u_scanf_register_handler (UChar spec,
00098 u_scanf_info info,
00099 u_scanf_handler handler)
00100 {
00101
00102 umtx_lock(0);
00103
00104
00105 g_u_scanf_infos[ (unsigned char) spec ] = info;
00106 g_u_scanf_handlers[ (unsigned char) spec ] = handler;
00107
00108
00109 umtx_unlock(0);
00110 return 0;
00111 }
00112
00113 int32_t
00114 u_scanf_skip_leading_ws(UFILE *stream,
00115 UChar pad)
00116 {
00117 UChar c;
00118 int32_t count = 0;
00119
00120
00121 while( ((c = u_fgetc(stream)) != 0xFFFF) && (c == pad || ufmt_isws(c)) )
00122 ++count;
00123
00124
00125 if(c != 0xFFFF)
00126 u_fungetc(c, stream);
00127
00128 return count;
00129 }
00130
00131 int32_t
00132 u_scanf_simple_percent_info(const u_scanf_spec_info *info,
00133 int32_t *argtypes,
00134 int32_t n)
00135 {
00136
00137 return 0;
00138 }
00139
00140 int32_t
00141 u_scanf_simple_percent_handler(UFILE *stream,
00142 const u_scanf_spec_info *info,
00143 ufmt_args *args,
00144 const UChar *fmt,
00145 int32_t *consumed)
00146 {
00147
00148 if(u_fgetc(stream) != 0x0025)
00149 return -1;
00150 else
00151 return 0;
00152 }
00153
00154 int32_t
00155 u_scanf_string_info(const u_scanf_spec_info *info,
00156 int32_t *argtypes,
00157 int32_t n)
00158 {
00159
00160 if(n < 1)
00161 return 0;
00162
00163
00164 argtypes[0] = ufmt_string;
00165 return 1;
00166 }
00167
00168 int32_t
00169 u_scanf_string_handler(UFILE *stream,
00170 const u_scanf_spec_info *info,
00171 ufmt_args *args,
00172 const UChar *fmt,
00173 int32_t *consumed)
00174 {
00175 UChar c;
00176 int32_t count;
00177 const UChar *source;
00178 UConverter *conv;
00179 UErrorCode status = U_ZERO_ERROR;
00180 char *arg = (char*)(args[0].ptrValue);
00181 char *alias = arg;
00182 char *limit;
00183
00184
00185 u_scanf_skip_leading_ws(stream, info->fPadChar);
00186
00187
00188 count = 0;
00189
00190
00191 conv = ucnv_open(ucnv_getDefaultName(), &status);
00192
00193 if(U_FAILURE(status))
00194 return -1;
00195
00196
00197 limit = alias + 2048;
00198
00199 while( ((c = u_fgetc(stream)) != 0xFFFF) &&
00200 (c != info->fPadChar && ! ufmt_isws(c)) &&
00201 (info->fWidth == -1 || count < info->fWidth) ) {
00202
00203
00204 source = &c;
00205
00206
00207 ucnv_fromUnicode(conv, &alias, limit, &source, source + 1,
00208 NULL, TRUE, &status);
00209
00210 if(U_FAILURE(status))
00211 return -1;
00212
00213
00214 ++count;
00215 }
00216
00217
00218 if(c != 0xFFFF)
00219 u_fungetc(c, stream);
00220
00221
00222 *alias = 0x00;
00223
00224
00225 ucnv_close(conv);
00226
00227
00228 return 1;
00229 }
00230
00231 int32_t
00232 u_scanf_ustring_info(const u_scanf_spec_info *info,
00233 int32_t *argtypes,
00234 int32_t n)
00235 {
00236
00237 if(n < 1)
00238 return 0;
00239
00240
00241 argtypes[0] = ufmt_ustring;
00242 return 1;
00243 }
00244
00245 int32_t
00246 u_scanf_ustring_handler(UFILE *stream,
00247 const u_scanf_spec_info *info,
00248 ufmt_args *args,
00249 const UChar *fmt,
00250 int32_t *consumed)
00251 {
00252 UChar c;
00253 int32_t count;
00254 UChar *arg = (UChar*)(args[0].ptrValue);
00255 UChar *alias = arg;
00256
00257
00258 u_scanf_skip_leading_ws(stream, info->fPadChar);
00259
00260
00261 count = 0;
00262
00263 while( ((c = u_fgetc(stream)) != 0xFFFF) &&
00264 (c != info->fPadChar && ! ufmt_isws(c)) &&
00265 (info->fWidth == -1 || count < info->fWidth) ) {
00266
00267
00268 *alias++ = c;
00269
00270
00271 ++count;
00272 }
00273
00274
00275 if(c != 0xFFFF)
00276 u_fungetc(c, stream);
00277
00278
00279 *alias = 0x0000;
00280
00281
00282 return 1;
00283 }
00284
00285
00286 int32_t
00287 u_scanf_count_info(const u_scanf_spec_info *info,
00288 int32_t *argtypes,
00289 int32_t n)
00290 {
00291
00292 if(n < 1)
00293 return 0;
00294
00295
00296 argtypes[0] = ufmt_count;
00297 return 1;
00298 }
00299
00300 int32_t
00301 u_scanf_count_handler(UFILE *stream,
00302 const u_scanf_spec_info *info,
00303 ufmt_args *args,
00304 const UChar *fmt,
00305 int32_t *consumed)
00306 {
00307 int *converted = (int*)(args[0].ptrValue);
00308
00309
00310
00311 *converted = info->fWidth;
00312
00313
00314 return 0;
00315 }
00316
00317 int32_t
00318 u_scanf_integer_info(const u_scanf_spec_info *info,
00319 int32_t *argtypes,
00320 int32_t n)
00321 {
00322
00323 if(n < 1)
00324 return 0;
00325
00326
00327 argtypes[0] = ufmt_int;
00328 return 1;
00329 }
00330
00331 int32_t
00332 u_scanf_integer_handler(UFILE *stream,
00333 const u_scanf_spec_info *info,
00334 ufmt_args *args,
00335 const UChar *fmt,
00336 int32_t *consumed)
00337 {
00338 int32_t len;
00339 long *num = (long*) (args[0].ptrValue);
00340 UNumberFormat *format;
00341 int32_t parsePos = 0;
00342 UErrorCode status = U_ZERO_ERROR;
00343
00344
00345
00346 u_scanf_skip_leading_ws(stream, info->fPadChar);
00347
00348
00349 ufile_fill_uchar_buffer(stream);
00350
00351
00352 len = stream->fUCLimit - stream->fUCPos;
00353
00354
00355 if(info->fWidth != -1)
00356 len = ufmt_min(len, info->fWidth);
00357
00358
00359 format = u_locbund_getNumberFormat(stream->fBundle);
00360
00361
00362 if(format == 0)
00363 return 0;
00364
00365
00366 *num = unum_parse(format, stream->fUCPos, len, &parsePos, &status);
00367
00368
00369 if(info->fIsShort)
00370 *num &= SHRT_MAX;
00371 else if(! info->fIsLong || ! info->fIsLongLong)
00372 *num &= INT_MAX;
00373
00374
00375 stream->fUCPos += parsePos;
00376
00377
00378 return 1;
00379 }
00380
00381 int32_t
00382 u_scanf_double_info(const u_scanf_spec_info *info,
00383 int32_t *argtypes,
00384 int32_t n)
00385 {
00386
00387 if(n < 1)
00388 return 0;
00389
00390
00391 argtypes[0] = ufmt_double;
00392 return 1;
00393 }
00394
00395 int32_t
00396 u_scanf_double_handler(UFILE *stream,
00397 const u_scanf_spec_info *info,
00398 ufmt_args *args,
00399 const UChar *fmt,
00400 int32_t *consumed)
00401 {
00402 int32_t len;
00403 double *num = (double*) (args[0].ptrValue);
00404 UNumberFormat *format;
00405 int32_t parsePos = 0;
00406 UErrorCode status = U_ZERO_ERROR;
00407
00408
00409
00410 u_scanf_skip_leading_ws(stream, info->fPadChar);
00411
00412
00413 ufile_fill_uchar_buffer(stream);
00414
00415
00416 len = stream->fUCLimit - stream->fUCPos;
00417
00418
00419 if(info->fWidth != -1)
00420 len = ufmt_min(len, info->fWidth);
00421
00422
00423 format = u_locbund_getNumberFormat(stream->fBundle);
00424
00425
00426 if(format == 0)
00427 return 0;
00428
00429
00430 *num = unum_parseDouble(format, stream->fUCPos, len, &parsePos, &status);
00431
00432
00433
00434
00435
00436
00437 stream->fUCPos += parsePos;
00438
00439
00440 return 1;
00441 }
00442
00443 int32_t
00444 u_scanf_scientific_info(const u_scanf_spec_info *info,
00445 int32_t *argtypes,
00446 int32_t n)
00447 {
00448
00449 if(n < 1)
00450 return 0;
00451
00452
00453 argtypes[0] = ufmt_double;
00454 return 1;
00455 }
00456
00457 int32_t
00458 u_scanf_scientific_handler(UFILE *stream,
00459 const u_scanf_spec_info *info,
00460 ufmt_args *args,
00461 const UChar *fmt,
00462 int32_t *consumed)
00463 {
00464 int32_t len;
00465 double *num = (double*) (args[0].ptrValue);
00466 UNumberFormat *format;
00467 int32_t parsePos = 0;
00468 UErrorCode status = U_ZERO_ERROR;
00469
00470
00471
00472 u_scanf_skip_leading_ws(stream, info->fPadChar);
00473
00474
00475 ufile_fill_uchar_buffer(stream);
00476
00477
00478 len = stream->fUCLimit - stream->fUCPos;
00479
00480
00481 if(info->fWidth != -1)
00482 len = ufmt_min(len, info->fWidth);
00483
00484
00485 format = u_locbund_getScientificFormat(stream->fBundle);
00486
00487
00488 if(format == 0)
00489 return 0;
00490
00491
00492 *num = unum_parseDouble(format, stream->fUCPos, len, &parsePos, &status);
00493
00494
00495
00496
00497
00498
00499 stream->fUCPos += parsePos;
00500
00501
00502 return 1;
00503 }
00504
00505 int32_t
00506 u_scanf_scidbl_info(const u_scanf_spec_info *info,
00507 int32_t *argtypes,
00508 int32_t n)
00509 {
00510
00511 if(n < 1)
00512 return 0;
00513
00514
00515 argtypes[0] = ufmt_double;
00516 return 1;
00517 }
00518
00519 int32_t
00520 u_scanf_scidbl_handler(UFILE *stream,
00521 const u_scanf_spec_info *info,
00522 ufmt_args *args,
00523 const UChar *fmt,
00524 int32_t *consumed)
00525 {
00526 int32_t len;
00527 double *num = (double*) (args[0].ptrValue);
00528 UNumberFormat *scientificFormat, *genericFormat;
00529
00530 double scientificResult, genericResult;
00531 int32_t scientificParsePos = 0, genericParsePos = 0;
00532 UErrorCode scientificStatus = U_ZERO_ERROR;
00533 UErrorCode genericStatus = U_ZERO_ERROR;
00534 UBool useScientific;
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544 u_scanf_skip_leading_ws(stream, info->fPadChar);
00545
00546
00547 ufile_fill_uchar_buffer(stream);
00548
00549
00550 len = stream->fUCLimit - stream->fUCPos;
00551
00552
00553 if(info->fWidth != -1)
00554 len = ufmt_min(len, info->fWidth);
00555
00556
00557 scientificFormat = u_locbund_getScientificFormat(stream->fBundle);
00558 genericFormat = u_locbund_getNumberFormat(stream->fBundle);
00559
00560
00561 if(scientificFormat == 0 || genericFormat == 0)
00562 return 0;
00563
00564
00565
00566 scientificResult = unum_parseDouble(scientificFormat, stream->fUCPos, len,
00567 &scientificParsePos, &scientificStatus);
00568
00569 genericResult = unum_parseDouble(genericFormat, stream->fUCPos, len,
00570 &genericParsePos, &genericStatus);
00571
00572
00573 useScientific = (UBool)(scientificParsePos > genericParsePos);
00574
00575
00576 *num = useScientific ? scientificResult : genericResult;
00577
00578
00579
00580
00581
00582
00583 stream->fUCPos += useScientific ? scientificParsePos : genericParsePos;
00584
00585
00586 return 1;
00587 }
00588
00589 int32_t
00590 u_scanf_currency_info(const u_scanf_spec_info *info,
00591 int32_t *argtypes,
00592 int32_t n)
00593 {
00594
00595 if(n < 1)
00596 return 0;
00597
00598
00599 argtypes[0] = ufmt_double;
00600 return 1;
00601 }
00602
00603 int32_t
00604 u_scanf_currency_handler(UFILE *stream,
00605 const u_scanf_spec_info *info,
00606 ufmt_args *args,
00607 const UChar *fmt,
00608 int32_t *consumed)
00609 {
00610 int32_t len;
00611 double *num = (double*) (args[0].ptrValue);
00612 UNumberFormat *format;
00613 int32_t parsePos = 0;
00614 UErrorCode status = U_ZERO_ERROR;
00615
00616
00617
00618 u_scanf_skip_leading_ws(stream, info->fPadChar);
00619
00620
00621 ufile_fill_uchar_buffer(stream);
00622
00623
00624 len = stream->fUCLimit - stream->fUCPos;
00625
00626
00627 if(info->fWidth != -1)
00628 len = ufmt_min(len, info->fWidth);
00629
00630
00631 format = u_locbund_getCurrencyFormat(stream->fBundle);
00632
00633
00634 if(format == 0)
00635 return 0;
00636
00637
00638 *num = unum_parseDouble(format, stream->fUCPos, len, &parsePos, &status);
00639
00640
00641
00642
00643
00644
00645 stream->fUCPos += parsePos;
00646
00647
00648 return 1;
00649 }
00650
00651 int32_t
00652 u_scanf_percent_info(const u_scanf_spec_info *info,
00653 int32_t *argtypes,
00654 int32_t n)
00655 {
00656
00657 if(n < 1)
00658 return 0;
00659
00660
00661 argtypes[0] = ufmt_double;
00662 return 1;
00663 }
00664
00665 int32_t
00666 u_scanf_percent_handler(UFILE *stream,
00667 const u_scanf_spec_info *info,
00668 ufmt_args *args,
00669 const UChar *fmt,
00670 int32_t *consumed)
00671 {
00672 int32_t len;
00673 double *num = (double*) (args[0].ptrValue);
00674 UNumberFormat *format;
00675 int32_t parsePos = 0;
00676 UErrorCode status = U_ZERO_ERROR;
00677
00678
00679
00680 u_scanf_skip_leading_ws(stream, info->fPadChar);
00681
00682
00683 ufile_fill_uchar_buffer(stream);
00684
00685
00686 len = stream->fUCLimit - stream->fUCPos;
00687
00688
00689 if(info->fWidth != -1)
00690 len = ufmt_min(len, info->fWidth);
00691
00692
00693 format = u_locbund_getPercentFormat(stream->fBundle);
00694
00695
00696 if(format == 0)
00697 return 0;
00698
00699
00700 *num = unum_parseDouble(format, stream->fUCPos, len, &parsePos, &status);
00701
00702
00703
00704
00705
00706
00707 stream->fUCPos += parsePos;
00708
00709
00710 return 1;
00711 }
00712
00713 int32_t
00714 u_scanf_date_info(const u_scanf_spec_info *info,
00715 int32_t *argtypes,
00716 int32_t n)
00717 {
00718
00719 if(n < 1)
00720 return 0;
00721
00722
00723 argtypes[0] = ufmt_date;
00724 return 1;
00725 }
00726
00727 int32_t
00728 u_scanf_date_handler(UFILE *stream,
00729 const u_scanf_spec_info *info,
00730 ufmt_args *args,
00731 const UChar *fmt,
00732 int32_t *consumed)
00733 {
00734 int32_t len;
00735 UDate *date = (UDate*) (args[0].ptrValue);
00736 UDateFormat *format;
00737 int32_t parsePos = 0;
00738 UErrorCode status = U_ZERO_ERROR;
00739
00740
00741
00742 u_scanf_skip_leading_ws(stream, info->fPadChar);
00743
00744
00745 ufile_fill_uchar_buffer(stream);
00746
00747
00748 len = stream->fUCLimit - stream->fUCPos;
00749
00750
00751 if(info->fWidth != -1)
00752 len = ufmt_min(len, info->fWidth);
00753
00754
00755 format = u_locbund_getDateFormat(stream->fBundle);
00756
00757
00758 if(format == 0)
00759 return 0;
00760
00761
00762 *date = udat_parse(format, stream->fUCPos, len, &parsePos, &status);
00763
00764
00765 stream->fUCPos += parsePos;
00766
00767
00768 return 1;
00769 }
00770
00771 int32_t
00772 u_scanf_time_info(const u_scanf_spec_info *info,
00773 int32_t *argtypes,
00774 int32_t n)
00775 {
00776
00777 if(n < 1)
00778 return 0;
00779
00780
00781 argtypes[0] = ufmt_date;
00782 return 1;
00783 }
00784
00785 int32_t
00786 u_scanf_time_handler(UFILE *stream,
00787 const u_scanf_spec_info *info,
00788 ufmt_args *args,
00789 const UChar *fmt,
00790 int32_t *consumed)
00791 {
00792 int32_t len;
00793 UDate *time = (UDate*) (args[0].ptrValue);
00794 UDateFormat *format;
00795 int32_t parsePos = 0;
00796 UErrorCode status = U_ZERO_ERROR;
00797
00798
00799
00800 u_scanf_skip_leading_ws(stream, info->fPadChar);
00801
00802
00803 ufile_fill_uchar_buffer(stream);
00804
00805
00806 len = stream->fUCLimit - stream->fUCPos;
00807
00808
00809 if(info->fWidth != -1)
00810 len = ufmt_min(len, info->fWidth);
00811
00812
00813 format = u_locbund_getTimeFormat(stream->fBundle);
00814
00815
00816 if(format == 0)
00817 return 0;
00818
00819
00820 *time = udat_parse(format, stream->fUCPos, len, &parsePos, &status);
00821
00822
00823 stream->fUCPos += parsePos;
00824
00825
00826 return 1;
00827 }
00828
00829 int32_t
00830 u_scanf_char_info(const u_scanf_spec_info *info,
00831 int32_t *argtypes,
00832 int32_t n)
00833 {
00834
00835 if(n < 1)
00836 return 0;
00837
00838
00839 argtypes[0] = ufmt_char;
00840 return 1;
00841 }
00842
00843 int32_t
00844 u_scanf_char_handler(UFILE *stream,
00845 const u_scanf_spec_info *info,
00846 ufmt_args *args,
00847 const UChar *fmt,
00848 int32_t *consumed)
00849 {
00850 UChar uc = 0;
00851 char *result;
00852 char *c = (char*)(args[0].ptrValue);
00853
00854
00855 u_scanf_skip_leading_ws(stream, info->fPadChar);
00856
00857
00858 if(info->fWidth == -1 || info->fWidth > 1)
00859 uc = u_fgetc(stream);
00860
00861
00862 if(uc == 0xFFFF)
00863 return -1;
00864
00865
00866 result = ufmt_unicodeToDefaultCP(&uc, 1);
00867 *c = result[0];
00868
00869
00870 free(result);
00871
00872
00873 return 1;
00874 }
00875
00876 int32_t
00877 u_scanf_uchar_info(const u_scanf_spec_info *info,
00878 int32_t *argtypes,
00879 int32_t n)
00880 {
00881
00882 if(n < 1)
00883 return 0;
00884
00885
00886 argtypes[0] = ufmt_uchar;
00887 return 1;
00888 }
00889
00890 int32_t
00891 u_scanf_uchar_handler(UFILE *stream,
00892 const u_scanf_spec_info *info,
00893 ufmt_args *args,
00894 const UChar *fmt,
00895 int32_t *consumed)
00896 {
00897 UChar *c = (UChar*)(args[0].ptrValue);
00898
00899
00900 u_scanf_skip_leading_ws(stream, info->fPadChar);
00901
00902
00903 if(info->fWidth == -1 || info->fWidth > 1)
00904 *c = u_fgetc(stream);
00905
00906
00907 if(*c == 0xFFFF)
00908 return -1;
00909
00910
00911 return 1;
00912 }
00913
00914 int32_t
00915 u_scanf_spellout_info(const u_scanf_spec_info *info,
00916 int32_t *argtypes,
00917 int32_t n)
00918 {
00919
00920 if(n < 1)
00921 return 0;
00922
00923
00924 argtypes[0] = ufmt_double;
00925 return 1;
00926 }
00927
00928 int32_t
00929 u_scanf_spellout_handler(UFILE *stream,
00930 const u_scanf_spec_info *info,
00931 ufmt_args *args,
00932 const UChar *fmt,
00933 int32_t *consumed)
00934 {
00935 int32_t len;
00936 double *num = (double*) (args[0].ptrValue);
00937 UNumberFormat *format;
00938 int32_t parsePos = 0;
00939 UErrorCode status = U_ZERO_ERROR;
00940
00941
00942
00943 u_scanf_skip_leading_ws(stream, info->fPadChar);
00944
00945
00946 ufile_fill_uchar_buffer(stream);
00947
00948
00949 len = stream->fUCLimit - stream->fUCPos;
00950
00951
00952 if(info->fWidth != -1)
00953 len = ufmt_min(len, info->fWidth);
00954
00955
00956 format = u_locbund_getSpelloutFormat(stream->fBundle);
00957
00958
00959 if(format == 0)
00960 return 0;
00961
00962
00963 *num = unum_parseDouble(format, stream->fUCPos, len, &parsePos, &status);
00964
00965
00966
00967
00968
00969
00970 stream->fUCPos += parsePos;
00971
00972
00973 return 1;
00974 }
00975
00976 int32_t
00977 u_scanf_hex_info(const u_scanf_spec_info *info,
00978 int32_t *argtypes,
00979 int32_t n)
00980 {
00981
00982 if(n < 1)
00983 return 0;
00984
00985
00986 argtypes[0] = ufmt_int;
00987 return 1;
00988 }
00989
00990 int32_t
00991 u_scanf_hex_handler(UFILE *stream,
00992 const u_scanf_spec_info *info,
00993 ufmt_args *args,
00994 const UChar *fmt,
00995 int32_t *consumed)
00996 {
00997 int32_t len;
00998 long *num = (long*) (args[0].ptrValue);
00999
01000
01001
01002 u_scanf_skip_leading_ws(stream, info->fPadChar);
01003
01004
01005 ufile_fill_uchar_buffer(stream);
01006
01007
01008 len = stream->fUCLimit - stream->fUCPos;
01009
01010
01011 if(info->fWidth != -1)
01012 len = ufmt_min(len, info->fWidth);
01013
01014
01015 if( *(stream->fUCPos) == 0x0030 &&
01016 (*(stream->fUCPos + 1) == 0x0078 || *(stream->fUCPos + 1) == 0x0058) ) {
01017
01018
01019 stream->fUCPos += 2;
01020 len -= 2;
01021 }
01022
01023
01024 *num = ufmt_utol(stream->fUCPos, &len, 16);
01025
01026
01027 stream->fUCPos += len;
01028
01029
01030 if(info->fIsShort)
01031 *num &= SHRT_MAX;
01032 else if(! info->fIsLong || ! info->fIsLongLong)
01033 *num &= INT_MAX;
01034
01035
01036 return 1;
01037 }
01038
01039 int32_t
01040 u_scanf_octal_info(const u_scanf_spec_info *info,
01041 int32_t *argtypes,
01042 int32_t n)
01043 {
01044
01045 if(n < 1)
01046 return 0;
01047
01048
01049 argtypes[0] = ufmt_int;
01050 return 1;
01051 }
01052
01053 int32_t
01054 u_scanf_octal_handler(UFILE *stream,
01055 const u_scanf_spec_info *info,
01056 ufmt_args *args,
01057 const UChar *fmt,
01058 int32_t *consumed)
01059 {
01060 int32_t len;
01061 long *num = (long*) (args[0].ptrValue);
01062
01063
01064
01065 u_scanf_skip_leading_ws(stream, info->fPadChar);
01066
01067
01068 ufile_fill_uchar_buffer(stream);
01069
01070
01071 len = stream->fUCLimit - stream->fUCPos;
01072
01073
01074 if(info->fWidth != -1)
01075 len = ufmt_min(len, info->fWidth);
01076
01077
01078 *num = ufmt_utol(stream->fUCPos, &len, 8);
01079
01080
01081 stream->fUCPos += len;
01082
01083
01084 if(info->fIsShort)
01085 *num &= SHRT_MAX;
01086 else if(! info->fIsLong || ! info->fIsLongLong)
01087 *num &= INT_MAX;
01088
01089
01090 return 1;
01091 }
01092
01093 int32_t
01094 u_scanf_pointer_info(const u_scanf_spec_info *info,
01095 int32_t *argtypes,
01096 int32_t n)
01097 {
01098
01099 if(n < 1)
01100 return 0;
01101
01102
01103 argtypes[0] = ufmt_pointer;
01104 return 1;
01105 }
01106
01107 int32_t
01108 u_scanf_pointer_handler(UFILE *stream,
01109 const u_scanf_spec_info *info,
01110 ufmt_args *args,
01111 const UChar *fmt,
01112 int32_t *consumed)
01113 {
01114 int32_t len;
01115 void *p = (void*)(args[0].ptrValue);
01116
01117
01118
01119 u_scanf_skip_leading_ws(stream, info->fPadChar);
01120
01121
01122 ufile_fill_uchar_buffer(stream);
01123
01124
01125 len = stream->fUCLimit - stream->fUCPos;
01126
01127
01128 if(info->fWidth != -1)
01129 len = ufmt_min(len, info->fWidth);
01130
01131
01132 *(void**)p = (void*) ufmt_utol(stream->fUCPos, &len, 16);
01133
01134
01135 stream->fUCPos += len;
01136
01137
01138 return 1;
01139 }
01140
01141 int32_t
01142 u_scanf_scanset_info(const u_scanf_spec_info *info,
01143 int32_t *argtypes,
01144 int32_t n)
01145 {
01146
01147 if(n < 1)
01148 return 0;
01149
01150
01151 argtypes[0] = ufmt_string;
01152 return 1;
01153 }
01154
01155 int32_t
01156 u_scanf_scanset_handler(UFILE *stream,
01157 const u_scanf_spec_info *info,
01158 ufmt_args *args,
01159 const UChar *fmt,
01160 int32_t *consumed)
01161 {
01162 u_scanf_scanset scanset;
01163 int32_t len;
01164 UBool success;
01165 UChar c;
01166 const UChar *source;
01167 UConverter *conv;
01168 UErrorCode status = U_ZERO_ERROR;
01169 char *s = (char*) (args[0].ptrValue);
01170 char *alias, *limit;
01171
01172
01173
01174 ufile_fill_uchar_buffer(stream);
01175
01176
01177 len = stream->fUCLimit - stream->fUCPos;
01178
01179
01180 if(info->fWidth != -1)
01181 len = ufmt_min(len, info->fWidth);
01182
01183
01184 alias = s;
01185 limit = alias + len;
01186
01187
01188 *consumed = u_strlen(fmt);
01189 success = u_scanf_scanset_init(&scanset, fmt, consumed);
01190
01191
01192 ++(*consumed);
01193
01194
01195 conv = ucnv_open(ucnv_getDefaultName(), &status);
01196
01197
01198 if(! success || U_FAILURE(status))
01199 return -1;
01200
01201
01202 while( (c = u_fgetc(stream)) != 0xFFFF && alias < limit) {
01203 if(u_scanf_scanset_in(&scanset, c)) {
01204 source = &c;
01205
01206 ucnv_fromUnicode(conv, &alias, limit, &source, source + 1,
01207 NULL, TRUE, &status);
01208
01209 if(U_FAILURE(status))
01210 return -1;
01211 }
01212
01213 else {
01214 break;
01215 }
01216 }
01217
01218
01219 if(c != 0xFFFF)
01220 u_fungetc(c, stream);
01221
01222
01223 if(alias == s)
01224 return -1;
01225
01226 else
01227 *alias = 0x00;
01228
01229
01230 ucnv_close(conv);
01231
01232
01233 return 1;
01234 }
01235
01236 void
01237 u_scanf_init(void)
01238 {
01239 int32_t i;
01240
01241
01242
01243 if(g_u_scanf_inited)
01244 return;
01245
01246
01247 umtx_lock(0);
01248
01249
01250 if(g_u_scanf_inited) {
01251 umtx_unlock(0);
01252 return;
01253 }
01254
01255
01256 for(i = 0; i < 256; ++i) {
01257 g_u_scanf_infos[i] = 0;
01258 g_u_scanf_handlers[i] = 0;
01259 }
01260
01261
01262
01263
01264
01265 g_u_scanf_infos[ 0x0025 ] = u_scanf_simple_percent_info;
01266 g_u_scanf_handlers[ 0x0025 ] = u_scanf_simple_percent_handler;
01267
01268
01269 g_u_scanf_infos[ 0x0073 ] = u_scanf_string_info;
01270 g_u_scanf_handlers[ 0x0073 ] = u_scanf_string_handler;
01271
01272
01273 g_u_scanf_infos[ 0x0055 ] = u_scanf_ustring_info;
01274 g_u_scanf_handlers[ 0x0055 ] = u_scanf_ustring_handler;
01275
01276
01277 g_u_scanf_infos[ 0x006E ] = u_scanf_count_info;
01278 g_u_scanf_handlers[ 0x006E ] = u_scanf_count_handler;
01279
01280
01281 g_u_scanf_infos[ 0x0064 ] = u_scanf_integer_info;
01282 g_u_scanf_handlers[ 0x0064 ] = u_scanf_integer_handler;
01283
01284
01285 g_u_scanf_infos[ 0x0069 ] = u_scanf_integer_info;
01286 g_u_scanf_handlers[ 0x0069 ] = u_scanf_integer_handler;
01287
01288
01289 g_u_scanf_infos[ 0x0075 ] = u_scanf_integer_info;
01290 g_u_scanf_handlers[ 0x0075 ] = u_scanf_integer_handler;
01291
01292
01293 g_u_scanf_infos[ 0x0066 ] = u_scanf_double_info;
01294 g_u_scanf_handlers[ 0x0066 ] = u_scanf_double_handler;
01295
01296
01297 g_u_scanf_infos[ 0x0065 ] = u_scanf_scientific_info;
01298 g_u_scanf_handlers[ 0x0065 ] = u_scanf_scientific_handler;
01299
01300
01301 g_u_scanf_infos[ 0x0045 ] = u_scanf_scientific_info;
01302 g_u_scanf_handlers[ 0x0045 ] = u_scanf_scientific_handler;
01303
01304
01305 g_u_scanf_infos[ 0x0067 ] = u_scanf_scidbl_info;
01306 g_u_scanf_handlers[ 0x0067 ] = u_scanf_scidbl_handler;
01307
01308
01309 g_u_scanf_infos[ 0x0047 ] = u_scanf_scidbl_info;
01310 g_u_scanf_handlers[ 0x0047 ] = u_scanf_scidbl_handler;
01311
01312
01313 g_u_scanf_infos[ 0x004D ] = u_scanf_currency_info;
01314 g_u_scanf_handlers[ 0x004D ] = u_scanf_currency_handler;
01315
01316
01317 g_u_scanf_infos[ 0x0050 ] = u_scanf_percent_info;
01318 g_u_scanf_handlers[ 0x0050 ] = u_scanf_percent_handler;
01319
01320
01321 g_u_scanf_infos[ 0x0044 ] = u_scanf_date_info;
01322 g_u_scanf_handlers[ 0x0044 ] = u_scanf_date_handler;
01323
01324
01325 g_u_scanf_infos[ 0x0054 ] = u_scanf_time_info;
01326 g_u_scanf_handlers[ 0x0054 ] = u_scanf_time_handler;
01327
01328
01329 g_u_scanf_infos[ 0x0063 ] = u_scanf_char_info;
01330 g_u_scanf_handlers[ 0x0063 ] = u_scanf_char_handler;
01331
01332
01333 g_u_scanf_infos[ 0x004B ] = u_scanf_uchar_info;
01334 g_u_scanf_handlers[ 0x004B ] = u_scanf_uchar_handler;
01335
01336
01337 g_u_scanf_infos[ 0x0056 ] = u_scanf_spellout_info;
01338 g_u_scanf_handlers[ 0x0056 ] = u_scanf_spellout_handler;
01339
01340
01341 g_u_scanf_infos[ 0x0078 ] = u_scanf_hex_info;
01342 g_u_scanf_handlers[ 0x0078 ] = u_scanf_hex_handler;
01343
01344
01345 g_u_scanf_infos[ 0x0058 ] = u_scanf_hex_info;
01346 g_u_scanf_handlers[ 0x0058 ] = u_scanf_hex_handler;
01347
01348
01349 g_u_scanf_infos[ 0x006F ] = u_scanf_octal_info;
01350 g_u_scanf_handlers[ 0x006F ] = u_scanf_octal_handler;
01351
01352
01353 g_u_scanf_infos[ 0x0070 ] = u_scanf_pointer_info;
01354 g_u_scanf_handlers[ 0x0070 ] = u_scanf_pointer_handler;
01355
01356
01357 g_u_scanf_infos[ 0x005B ] = u_scanf_scanset_info;
01358 g_u_scanf_handlers[ 0x005B ] = u_scanf_scanset_handler;
01359
01360
01361 g_u_scanf_inited = TRUE;
01362
01363
01364 umtx_unlock(0);
01365 }
01366
01367
01368 #define U_SCANF_MAX_ARGS 32
01369 #define UP_PERCENT 0x0025
01370
01371 int32_t
01372 u_vfscanf_u( UFILE *f,
01373 const UChar *patternSpecification,
01374 va_list ap)
01375 {
01376 u_scanf_spec spec;
01377 const UChar *alias;
01378 int32_t count, converted, temp;
01379
01380 int32_t num_args_wanted;
01381 int32_t ufmt_types [U_SCANF_MAX_ARGS];
01382 ufmt_args args [U_SCANF_MAX_ARGS];
01383
01384 u_scanf_info info;
01385 u_scanf_handler handler;
01386
01387 int32_t cur_arg;
01388
01389
01390
01391 if(! g_u_scanf_inited)
01392 u_scanf_init();
01393
01394
01395 alias = patternSpecification;
01396
01397
01398 converted = 0;
01399
01400
01401 for(;;) {
01402
01403
01404 while(*alias != UP_PERCENT && *alias != 0x0000 && u_fgetc(f) == *alias) {
01405 alias++;
01406 }
01407
01408
01409 if(*alias != UP_PERCENT || *alias == 0x0000)
01410 break;
01411
01412
01413 count = u_scanf_parse_spec(alias, &spec);
01414
01415
01416 alias += count;
01417
01418
01419 if(spec.fSkipArg)
01420 va_arg(ap, int);
01421
01422
01423 info = g_u_scanf_infos[ (unsigned char) spec.fInfo.fSpec ];
01424 if(info != 0) {
01425 num_args_wanted = (*info)(&spec.fInfo,
01426 ufmt_types,
01427 U_SCANF_MAX_ARGS);
01428 }
01429 else
01430 num_args_wanted = 0;
01431
01432
01433 for(cur_arg = 0;
01434 cur_arg < num_args_wanted && cur_arg < U_SCANF_MAX_ARGS;
01435 ++cur_arg) {
01436
01437 switch(ufmt_types[cur_arg]) {
01438
01439 case ufmt_count:
01440 args[cur_arg].intValue = va_arg(ap, int);
01441
01442 spec.fInfo.fWidth = converted;
01443 break;
01444
01445 case ufmt_int:
01446 args[cur_arg].ptrValue = va_arg(ap, int*);
01447 break;
01448
01449 case ufmt_char:
01450 args[cur_arg].ptrValue = va_arg(ap, int*);
01451 break;
01452
01453 case ufmt_wchar:
01454 args[cur_arg].ptrValue = va_arg(ap, wchar_t*);
01455 break;
01456
01457 case ufmt_string:
01458 args[cur_arg].ptrValue = va_arg(ap, char*);
01459 break;
01460
01461 case ufmt_wstring:
01462 args[cur_arg].ptrValue = va_arg(ap, wchar_t*);
01463 break;
01464
01465 case ufmt_pointer:
01466 args[cur_arg].ptrValue = va_arg(ap, void*);
01467 break;
01468
01469 case ufmt_float:
01470 args[cur_arg].ptrValue = va_arg(ap, float*);
01471 break;
01472
01473 case ufmt_double:
01474 args[cur_arg].ptrValue = va_arg(ap, double*);
01475 break;
01476
01477 case ufmt_date:
01478 args[cur_arg].ptrValue = va_arg(ap, UDate*);
01479 break;
01480
01481 case ufmt_ustring:
01482 args[cur_arg].ptrValue = va_arg(ap, UChar*);
01483 break;
01484
01485 case ufmt_uchar:
01486 args[cur_arg].ptrValue = va_arg(ap, int*);
01487 break;
01488 }
01489 }
01490
01491
01492 handler = g_u_scanf_handlers[ (unsigned char) spec.fInfo.fSpec ];
01493 if(handler != 0) {
01494
01495
01496 count = 0;
01497
01498 temp = (*handler)(f, &spec.fInfo, args, alias, &count);
01499
01500
01501 if(temp == -1)
01502 break;
01503
01504
01505 converted += temp;
01506
01507
01508 alias += count;
01509 }
01510
01511
01512
01513 }
01514
01515
01516 return converted;
01517 }
01518