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
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107 #include <_ansi.h>
00108
00109 #include <wctype.h>
00110 #include <stdio.h>
00111 #include <stdlib.h>
00112 #include <limits.h>
00113 #include <wchar.h>
00114 #include <string.h>
00115
00116
00117 #ifdef _HAVE_STDC
00118 #include <stdarg.h>
00119 #else
00120 #include <varargs.h>
00121 #endif
00122
00123 #ifndef SMALL_SCANF
00124 #include "local.h"
00125 #endif
00126
00127
00128 #ifndef NO_FLOATING_POINT
00129 #include <float.h>
00130 #endif
00131
00132
00133
00134 #ifndef NO_FLOATING_POINT
00135 #define FLOATING_POINT
00136 #endif
00137
00138 #ifdef FLOATING_POINT
00139 #include <float.h>
00140
00141
00142
00143
00144 #define _NO_LONGDBL
00145 #if defined WANT_IO_LONG_DBL && (LDBL_MANT_DIG > DBL_MANT_DIG)
00146 #undef _NO_LONGDBL
00147 extern _LONG_DOUBLE _strtold _PARAMS((char *s, char **sptr));
00148 #endif
00149
00150 #define _NO_LONGLONG
00151 #if defined WANT_PRINTF_LONG_LONG && defined __GNUC__
00152 # undef _NO_LONGLONG
00153 #endif
00154
00155 #include "floatio.h"
00156
00157 #if ((MAXEXP+MAXFRACT+3) > MB_LEN_MAX)
00158 # define BUF (MAXEXP+MAXFRACT+3)
00159 #else
00160 # define BUF MB_LEN_MAX
00161 #endif
00162
00163
00164
00165 #define MAX_LONG_LEN ((CHAR_BIT * sizeof (long) - 1) * 4 / 13 + 2)
00166 #else
00167 #define BUF 40
00168 #endif
00169
00170
00171
00172
00173
00174
00175 #define LONG 0x01
00176 #define LONGDBL 0x02
00177 #define SHORT 0x04
00178 #define CHAR 0x08
00179 #define SUPPRESS 0x10
00180 #define POINTER 0x20
00181 #define NOSKIP 0x40
00182
00183
00184
00185
00186
00187
00188
00189 #define SIGNOK 0x80
00190 #define NDIGITS 0x100
00191
00192 #define DPTOK 0x200
00193 #define EXPOK 0x400
00194
00195 #define PFXOK 0x200
00196 #define NZDIGITS 0x400
00197
00198
00199
00200
00201
00202 #define CT_CHAR 0
00203 #define CT_CCL 1
00204 #define CT_STRING 2
00205 #define CT_INT 3
00206 #define CT_FLOAT 4
00207
00208 #if 0
00209 #define u_char unsigned char
00210 #endif
00211 #define u_char char
00212 #define u_long unsigned long
00213
00214 #ifndef _NO_LONGLONG
00215 typedef unsigned long long u_long_long;
00216 #endif
00217
00218 u_char *__sccl ();
00219
00220
00221
00222
00223
00224 #ifndef SMALL_SCANF
00225 #define BufferEmpty (fp->_r <= 0 && __srefill(fp))
00226
00227 #else // SMALL_SCANF
00228
00229 unsigned char buf_ungetc ;
00230 int flag_buf_ungetc = 0 ;
00231 #define buf_ungetc_empty 0
00232 #define buf_ungetc_full 1
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247 int __io_ungetc(int c){
00248
00249 if (flag_buf_ungetc == 0){
00250 flag_buf_ungetc = buf_ungetc_full;
00251 }
00252 buf_ungetc= (unsigned char)c ;
00253
00254 return (c);
00255 }
00256
00257 int new_getchar() {
00258 if (flag_buf_ungetc == 0){
00259
00260 return __io_getchar();
00261
00262 }
00263 else {
00264
00265 flag_buf_ungetc = buf_ungetc_empty;
00266 return buf_ungetc;
00267
00268 }
00269
00270 }
00271
00272 #endif // SMALL_SCANF
00273
00274 #ifndef _REENT_ONLY
00275
00276 int
00277 _DEFUN (vfscanf, (fp, fmt, ap),
00278 register FILE *fp _AND
00279 _CONST char *fmt _AND
00280 va_list ap)
00281 {
00282
00283 #ifndef SMALL_SCANF
00284 CHECK_INIT(fp);
00285 #endif
00286
00287 return __svfscanf_r (_REENT, fp, fmt, ap);
00288 }
00289
00290 int
00291 __svfscanf (fp, fmt0, ap)
00292 register FILE *fp;
00293 char _CONST *fmt0;
00294 va_list ap;
00295 {
00296 return __svfscanf_r (_REENT, fp, fmt0, ap);
00297 }
00298
00299 #endif
00300
00301 int
00302 _DEFUN (_vfscanf_r, (data, fp, fmt, ap),
00303 struct _reent *data _AND
00304 register FILE *fp _AND
00305 _CONST char *fmt _AND
00306 va_list ap)
00307 {
00308 return __svfscanf_r (data, fp, fmt, ap);
00309 }
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326 int
00327 __svfscanf_r (rptr, fp, fmt0, ap)
00328 struct _reent *rptr;
00329 register FILE *fp;
00330 char _CONST *fmt0;
00331 va_list ap;
00332 {
00333
00334 register char * bufread;
00335 register u_char *fmt = (u_char *) fmt0;
00336 register int c;
00337 register int car;
00338 register size_t width;
00339 register char *p;
00340 register int n;
00341 register int flags;
00342 register char *p0;
00343 int nassigned;
00344 int nread;
00345 int base = 0;
00346 int nbytes = 1;
00347 wchar_t wc;
00348 wchar_t *wcp;
00349 size_t mbslen;
00350 mbstate_t state;
00351
00352 u_long (*ccfn) () = 0;
00353 char ccltab[256];
00354 char buf[BUF];
00355 char *lptr;
00356
00357 char *cp;
00358 short *sp;
00359 int *ip;
00360 float *flp;
00361 _LONG_DOUBLE *ldp;
00362 double *dp;
00363 long *lp;
00364 #ifndef _NO_LONGLONG
00365 long long *llp;
00366 #endif
00367
00368
00369 static _CONST short basefix[17] =
00370 {10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
00371
00372 nassigned = 0;
00373 nread = 0;
00374 for (;;)
00375 {
00376 #ifndef MB_CAPABLE
00377 wc = *fmt;
00378 #else
00379 memset (&state, '\0', sizeof (state));
00380 nbytes = _mbtowc_r (rptr, &wc, fmt, MB_CUR_MAX, &state);
00381 #endif
00382 fmt += nbytes;
00383 if (wc == 0)
00384 return nassigned;
00385 if (nbytes == 1 && isspace (wc))
00386 {
00387 for (;;)
00388 {
00389 #ifndef SMALL_SCANF
00390 if (BufferEmpty || !isspace (*fp->_p))
00391 break;
00392 nread++, fp->_r--, fp->_p++;
00393
00394 #else
00395 if (!isspace (*fp->_p)) break;
00396 nread++, fp->_r--;
00397 *fp->_p = new_getchar();
00398
00399 #endif
00400 }
00401
00402 continue;
00403 }
00404 if (wc != '%')
00405 goto literal;
00406 width = 0;
00407 flags = 0;
00408
00409
00410
00411
00412
00413
00414 again:
00415 c = *fmt++;
00416 switch (c)
00417 {
00418 case '%':
00419 literal:
00420 lptr = fmt - nbytes;
00421 for (n = 0; n < nbytes; ++n)
00422 {
00423 #ifndef SMALL_SCANF
00424 if (BufferEmpty)
00425 goto input_failure;
00426 #else
00427 *fp->_p = new_getchar();
00428 #endif
00429
00430 if (*fp->_p != *lptr)
00431 goto match_failure;
00432 #ifndef SMALL_SCANF
00433 fp->_r--, fp->_p++;
00434 nread++;
00435 #else
00436 fp->_r--;
00437 *fp->_p = new_getchar();
00438 nread++;
00439 #endif
00440 ++lptr;
00441 }
00442 continue;
00443
00444 case '*':
00445 flags |= SUPPRESS;
00446 goto again;
00447 case 'l':
00448 if (*fmt == 'l')
00449 {
00450 ++fmt;
00451 flags |= LONGDBL;
00452 }
00453 else
00454 flags |= LONG;
00455 goto again;
00456 case 'L':
00457 flags |= LONGDBL;
00458 goto again;
00459 case 'h':
00460 if (*fmt == 'h')
00461 {
00462 ++fmt;
00463 flags |= CHAR;
00464 }
00465 else
00466 flags |= SHORT;
00467 goto again;
00468
00469 case '0':
00470 case '1':
00471 case '2':
00472 case '3':
00473 case '4':
00474 case '5':
00475 case '6':
00476 case '7':
00477 case '8':
00478 case '9':
00479 width = width * 10 + c - '0';
00480 goto again;
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490 case 'D':
00491 flags |= LONG;
00492
00493 case 'd':
00494 c = CT_INT;
00495 ccfn = (u_long (*)())_strtol_r;
00496 base = 10;
00497 break;
00498
00499 case 'i':
00500 c = CT_INT;
00501 ccfn = (u_long (*)())_strtol_r;
00502 base = 0;
00503 break;
00504
00505 case 'O':
00506 flags |= LONG;
00507
00508 case 'o':
00509 c = CT_INT;
00510 ccfn = _strtoul_r;
00511 base = 8;
00512 break;
00513
00514 case 'u':
00515 c = CT_INT;
00516 ccfn = _strtoul_r;
00517 base = 10;
00518 break;
00519
00520 case 'X':
00521 case 'x':
00522 flags |= PFXOK;
00523 c = CT_INT;
00524 ccfn = _strtoul_r;
00525 base = 16;
00526 break;
00527
00528 #ifdef FLOATING_POINT
00529 case 'E':
00530 case 'G':
00531
00532
00533 case 'e':
00534 case 'f':
00535 case 'g':
00536 c = CT_FLOAT;
00537 break;
00538 #endif
00539 case 'S':
00540 flags |= LONG;
00541
00542
00543 case 's':
00544 c = CT_STRING;
00545 break;
00546
00547 case '[':
00548 fmt = __sccl (ccltab, fmt);
00549 flags |= NOSKIP;
00550 c = CT_CCL;
00551 break;
00552
00553 case 'C':
00554 flags |= LONG;
00555
00556
00557 case 'c':
00558 flags |= NOSKIP;
00559 c = CT_CHAR;
00560 break;
00561
00562 case 'p':
00563 flags |= POINTER | PFXOK;
00564 c = CT_INT;
00565 ccfn = _strtoul_r;
00566 base = 16;
00567 break;
00568
00569 case 'n':
00570 if (flags & SUPPRESS)
00571 continue;
00572 if (flags & CHAR)
00573 {
00574 cp = va_arg (ap, char *);
00575 *cp = nread;
00576 }
00577 else if (flags & SHORT)
00578 {
00579 sp = va_arg (ap, short *);
00580 *sp = nread;
00581 }
00582 else if (flags & LONG)
00583 {
00584 lp = va_arg (ap, long *);
00585 *lp = nread;
00586 }
00587 #ifndef _NO_LONGLONG
00588 else if (flags & LONGDBL)
00589 {
00590 llp = va_arg (ap, long long*);
00591 *llp = nread;
00592 }
00593 #endif
00594 else
00595 {
00596 ip = va_arg (ap, int *);
00597 *ip = nread;
00598 }
00599 continue;
00600
00601
00602
00603
00604 case '\0':
00605 return EOF;
00606
00607 default:
00608 if (isupper (c))
00609 flags |= LONG;
00610 c = CT_INT;
00611 ccfn = (u_long (*)())_strtol_r;
00612 base = 10;
00613 break;
00614 }
00615
00616
00617
00618
00619 #ifndef SMALL_SCANF
00620 if (BufferEmpty)
00621 goto input_failure;
00622 #else
00623 *fp->_p = new_getchar();
00624 #endif
00625
00626
00627
00628
00629
00630
00631 if ((flags & NOSKIP) == 0)
00632 {
00633 while (isspace (*fp->_p))
00634 {
00635 #ifndef SMALL_SCANF
00636 nread++;
00637 if (--fp->_r > 0)
00638 fp->_p++;
00639 else
00640 if (__srefill (fp))
00641 goto input_failure;
00642 #else
00643 *fp->_p = new_getchar();
00644 #endif
00645 }
00646
00647
00648
00649
00650
00651 }
00652
00653
00654
00655
00656 switch (c)
00657 {
00658
00659 case CT_CHAR:
00660
00661 if (width == 0)
00662 width = 1;
00663 if (flags & LONG)
00664 {
00665 if ((flags & SUPPRESS) == 0)
00666 wcp = va_arg(ap, wchar_t *);
00667 else
00668 wcp = NULL;
00669 n = 0;
00670 while (width != 0)
00671 {
00672
00673 if (n == MB_CUR_MAX)
00674 goto input_failure;
00675 #ifndef SMALL_SCANF
00676 buf[n++] = *fp->_p;
00677 fp->_r -= 1;
00678 fp->_p += 1;
00679 memset((void *)&state, '\0', sizeof(mbstate_t));
00680 if ((mbslen = _mbrtowc_r(rptr, wcp, buf, n, &state))
00681 == (size_t)-1)
00682 goto input_failure;
00683 #else
00684 buf[n++] = *fp->_p;
00685 *fp->_p = new_getchar();
00686
00687 #endif
00688
00689 if (mbslen == 0 && !(flags & SUPPRESS))
00690 *wcp = L'\0';
00691 if (mbslen != (size_t)-2)
00692 {
00693 nread += n;
00694 width -= 1;
00695 if (!(flags & SUPPRESS))
00696 wcp += 1;
00697 n = 0;
00698 }
00699 #ifndef SMALL_SCANF
00700 if (BufferEmpty)
00701 {
00702 if (n != 0)
00703 goto input_failure;
00704 break;
00705 }
00706 #endif
00707 }
00708 if (!(flags & SUPPRESS))
00709 nassigned++;
00710 }
00711 else if (flags & SUPPRESS)
00712 {
00713 size_t sum = 0;
00714 for (;;)
00715 {
00716 if ((n = fp->_r) < (int)width)
00717 {
00718 sum += n;
00719 width -= n;
00720 #ifndef SMALL_SCANF
00721 fp->_p += n;
00722 if (__srefill (fp))
00723 {
00724 if (sum == 0)
00725 goto input_failure;
00726 break;
00727 }
00728 #else
00729 *fp->_p = new_getchar();
00730 #endif
00731
00732 }
00733 else
00734 {
00735 sum += width;
00736 fp->_r -= width;
00737 #ifndef SMALL_SCANF
00738 fp->_p += width;
00739 #else
00740 *fp->_p = new_getchar();
00741 #endif
00742
00743 break;
00744 }
00745 }
00746 nread += sum;
00747 }
00748 else
00749 {
00750
00751 #ifndef SMALL_SCANF
00752 size_t r = fread ((_PTR) va_arg (ap, char *), 1, width, fp);
00753 if (r == 0)
00754 goto input_failure;
00755 nread += r;
00756 nassigned++;
00757
00758 #else
00759 bufread=(_PTR)va_arg(ap,char *);
00760 int r;
00761 for (r=0;r<width;r++){
00762 *bufread++= *fp->_p;
00763 if ( r+1 < width){
00764 *fp->_p = new_getchar();
00765 }
00766 }
00767 #endif
00768 }
00769 break;
00770
00771 case CT_CCL:
00772
00773 if (width == 0)
00774 width = ~0;
00775
00776 if (flags & SUPPRESS)
00777 {
00778 n = 0;
00779 while (ccltab[*fp->_p])
00780 {
00781 #ifndef SMALL_SCANF
00782 n++, fp->_r--, fp->_p++;
00783 if (--width == 0)
00784 break;
00785 if (BufferEmpty)
00786 {
00787 if (n == 0)
00788 goto input_failure;
00789 break;
00790 }
00791 #else
00792 n++;
00793 fp->_r++;
00794 *fp->_p = new_getchar();
00795 #endif
00796
00797 }
00798 if (n == 0)
00799 goto match_failure;
00800 }
00801 else
00802 {
00803 p0 = p = va_arg (ap, char *);
00804 while (ccltab[*fp->_p])
00805 {
00806 fp->_r--;
00807 #ifndef SMALL_SCANF
00808 *p++ = *fp->_p++;
00809 if (--width == 0)
00810 break;
00811 if (BufferEmpty)
00812 {
00813 if (p == p0)
00814 goto input_failure;
00815 break;
00816 }
00817 #else
00818 *p++ = *fp->_p;
00819 *fp->_p= new_getchar();
00820 if (--width == 0)
00821 break;
00822 #endif
00823
00824 }
00825 n = p - p0;
00826 if (n == 0)
00827 goto match_failure;
00828 *p = 0;
00829 nassigned++;
00830 }
00831 nread += n;
00832 break;
00833
00834 case CT_STRING:
00835
00836
00837 if (width == 0)
00838 width = (size_t)~0;
00839 if (flags & LONG)
00840 {
00841
00842 if ((flags & SUPPRESS) == 0)
00843 wcp = va_arg(ap, wchar_t *);
00844 else
00845 wcp = &wc;
00846 n = 0;
00847 while (!isspace(*fp->_p) && width != 0)
00848 {
00849 if (n == MB_CUR_MAX)
00850 goto input_failure;
00851 buf[n++] = *fp->_p;
00852 fp->_r -= 1;
00853 #ifndef SMALL_SCANF
00854 fp->_p += 1;
00855 memset((void *)&state, '\0', sizeof(mbstate_t));
00856 if ((mbslen = _mbrtowc_r(rptr, wcp, buf, n, &state))
00857 == (size_t)-1)
00858 goto input_failure;
00859 #else
00860 *fp->_p = new_getchar();
00861 #endif
00862
00863 if (mbslen == 0)
00864 *wcp = L'\0';
00865
00866 if (mbslen != (size_t)-2)
00867 {
00868 if (iswspace(*wcp))
00869 {
00870
00871 while (n != 0)
00872 #ifndef SMALL_SCANF
00873 ungetc(buf[--n], fp);
00874 #else
00875 __io_ungetc(buf[--n]);
00876 #endif
00877 break;
00878
00879 }
00880
00881 nread += n;
00882 width -= 1;
00883 if ((flags & SUPPRESS) == 0)
00884 wcp += 1;
00885 n = 0;
00886 }
00887 #ifndef SMALL_SCANF
00888 if (BufferEmpty)
00889 {
00890 if (n != 0)
00891 goto input_failure;
00892 break;
00893 }
00894 #endif
00895
00896 }
00897 if (!(flags & SUPPRESS))
00898 {
00899 *wcp = L'\0';
00900 nassigned++;
00901 }
00902 }
00903 else if (flags & SUPPRESS)
00904 {
00905 n = 0;
00906 while (!isspace (*fp->_p))
00907 {
00908 #ifndef SMALL_SCANF
00909 n++, fp->_r--, fp->_p++;
00910 if (--width == 0)
00911 break;
00912 if (BufferEmpty)
00913 break;
00914 #else
00915 n++;
00916 *fp->_p = new_getchar();
00917 if (*fp->_p == '\0') break;
00918 #endif
00919
00920 }
00921 nread += n;
00922 }
00923 else
00924 {
00925 p0 = p = va_arg (ap, char *);
00926 while (!isspace (*fp->_p))
00927 {
00928 #ifndef SMALL_SCANF
00929 fp->_r--;
00930 *p++ = *fp->_p++;
00931 if (--width == 0)
00932 break;
00933 if (BufferEmpty)
00934 break;
00935 #else
00936 *p++=*fp->_p;
00937 *fp->_p = new_getchar();
00938 if (*fp->_p == '\0') break;
00939 #endif
00940
00941
00942 }
00943 *p = 0;
00944 nread += p - p0;
00945 nassigned++;
00946 }
00947 continue;
00948
00949 case CT_INT:
00950
00951 #ifdef hardway
00952 if (width == 0 || width > sizeof (buf) - 1)
00953 width = sizeof (buf) - 1;
00954 #else
00955
00956 if (--width > sizeof (buf) - 2)
00957 width = sizeof (buf) - 2;
00958 width++;
00959 #endif
00960 flags |= SIGNOK | NDIGITS | NZDIGITS;
00961 for (p = buf; width; width--)
00962 {
00963 c = *fp->_p;
00964
00965
00966
00967
00968 switch (c)
00969 {
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979 case '0':
00980 if (base == 0)
00981 {
00982 base = 8;
00983 flags |= PFXOK;
00984 }
00985 if (flags & NZDIGITS)
00986 flags &= ~(SIGNOK | NZDIGITS | NDIGITS);
00987 else
00988 flags &= ~(SIGNOK | PFXOK | NDIGITS);
00989 goto ok;
00990
00991
00992 case '1':
00993 case '2':
00994 case '3':
00995 case '4':
00996 case '5':
00997 case '6':
00998 case '7':
00999 base = basefix[base];
01000 flags &= ~(SIGNOK | PFXOK | NDIGITS);
01001 goto ok;
01002
01003
01004 case '8':
01005 case '9':
01006 base = basefix[base];
01007 if (base <= 8)
01008 break;
01009 flags &= ~(SIGNOK | PFXOK | NDIGITS);
01010 goto ok;
01011
01012
01013 case 'A':
01014 case 'B':
01015 case 'C':
01016 case 'D':
01017 case 'E':
01018 case 'F':
01019 case 'a':
01020 case 'b':
01021 case 'c':
01022 case 'd':
01023 case 'e':
01024 case 'f':
01025
01026 if (base <= 10)
01027 break;
01028 flags &= ~(SIGNOK | PFXOK | NDIGITS);
01029 goto ok;
01030
01031
01032 case '+':
01033 case '-':
01034 if (flags & SIGNOK)
01035 {
01036 flags &= ~SIGNOK;
01037 goto ok;
01038 }
01039 break;
01040
01041
01042 case 'x':
01043 case 'X':
01044 if (flags & PFXOK && p == buf + 1)
01045 {
01046 base = 16;
01047 flags &= ~PFXOK;
01048 goto ok;
01049 }
01050 break;
01051 }
01052
01053
01054
01055
01056
01057 break;
01058 ok:
01059
01060
01061
01062 *p++ = c;
01063 #ifndef SMALL_SCANF
01064 if (--fp->_r > 0)
01065 fp->_p++;
01066 else
01067 if (__srefill (fp))
01068 break;
01069 #else
01070
01071 *fp->_p = new_getchar();
01072
01073 #endif
01074
01075 }
01076
01077
01078
01079
01080
01081
01082 if (flags & NDIGITS)
01083 {
01084 if (p > buf)
01085 #ifndef SMALL_SCANF
01086 _CAST_VOID ungetc (*(u_char *)-- p, fp);
01087 #else
01088 _CAST_VOID __io_ungetc (*(u_char *)-- p);
01089 #endif
01090 goto match_failure;
01091
01092 }
01093
01094 c = ((u_char *) p)[-1];
01095 if (c == 'x' || c == 'X')
01096 {
01097 --p;
01098 #ifndef SMALL_SCANF
01099 ungetc (c, fp);
01100 #else
01101 __io_ungetc (c);
01102 #endif
01103
01104 }
01105 if ((flags & SUPPRESS) == 0)
01106 {
01107 u_long res;
01108
01109 *p = 0;
01110 res = (*ccfn) (rptr, buf, (char **) NULL, base);
01111 if (flags & POINTER)
01112 *(va_arg (ap, _PTR *)) = (_PTR) (unsigned _POINTER_INT) res;
01113 else if (flags & CHAR)
01114 {
01115 cp = va_arg (ap, char *);
01116 *cp = res;
01117 }
01118 else if (flags & SHORT)
01119 {
01120 sp = va_arg (ap, short *);
01121 *sp = res;
01122 }
01123 else if (flags & LONG)
01124 {
01125 lp = va_arg (ap, long *);
01126 *lp = res;
01127 }
01128 #ifndef _NO_LONGLONG
01129 else if (flags & LONGDBL)
01130 {
01131 u_long_long resll;
01132 if (ccfn == _strtoul_r)
01133 resll = _strtoull_r (rptr, buf, (char **) NULL, base);
01134 else
01135 resll = _strtoll_r (rptr, buf, (char **) NULL, base);
01136 llp = va_arg (ap, long long*);
01137 *llp = resll;
01138 }
01139 #endif
01140 else
01141 {
01142 ip = va_arg (ap, int *);
01143 *ip = res;
01144 }
01145 nassigned++;
01146 }
01147 nread += p - buf;
01148 break;
01149
01150 #ifdef FLOATING_POINT
01151 case CT_FLOAT:
01152 {
01153
01154
01155
01156
01157
01158 long leading_zeroes = 0;
01159 long zeroes, exp_adjust;
01160 char *exp_start = NULL;
01161 #ifdef hardway
01162 if (width == 0 || width > sizeof (buf) - 1)
01163 width = sizeof (buf) - 1;
01164 #else
01165
01166 if (--width > sizeof (buf) - 2)
01167 width = sizeof (buf) - 2;
01168 width++;
01169 #endif
01170 flags |= SIGNOK | NDIGITS | DPTOK | EXPOK;
01171 zeroes = 0;
01172 exp_adjust = 0;
01173 for (p = buf; width; )
01174 {
01175 c = *fp->_p;
01176
01177
01178
01179
01180 switch (c)
01181 {
01182
01183 case '0':
01184 if (flags & NDIGITS)
01185 {
01186 flags &= ~SIGNOK;
01187 zeroes++;
01188 goto fskip;
01189 }
01190
01191 case '1':
01192 case '2':
01193 case '3':
01194 case '4':
01195 case '5':
01196 case '6':
01197 case '7':
01198 case '8':
01199 case '9':
01200 flags &= ~(SIGNOK | NDIGITS);
01201 goto fok;
01202
01203 case '+':
01204 case '-':
01205 if (flags & SIGNOK)
01206 {
01207 flags &= ~SIGNOK;
01208 goto fok;
01209 }
01210 break;
01211 case '.':
01212 if (flags & DPTOK)
01213 {
01214 flags &= ~(SIGNOK | DPTOK);
01215 leading_zeroes = zeroes;
01216 goto fok;
01217 }
01218 break;
01219 case 'e':
01220 case 'E':
01221
01222 if ((flags & (NDIGITS | EXPOK)) == EXPOK
01223 || ((flags & EXPOK) && zeroes))
01224 {
01225 if (! (flags & DPTOK))
01226 {
01227 exp_adjust = zeroes - leading_zeroes;
01228 exp_start = p;
01229 }
01230 flags =
01231 (flags & ~(EXPOK | DPTOK)) |
01232 SIGNOK | NDIGITS;
01233 zeroes = 0;
01234 goto fok;
01235 }
01236 break;
01237 }
01238 break;
01239 fok:
01240 *p++ = c;
01241 fskip:
01242 width--;
01243 ++nread;
01244 #ifndef SMALL_SCANF
01245 if (--fp->_r > 0)
01246 fp->_p++;
01247 else
01248 if (__srefill (fp))
01249 break;
01250 #else
01251 *fp->_p = new_getchar();
01252 if ( (47<*fp->_p<58) && (64<*fp->_p < 71) && (96<*fp->_p<103) ){
01253 ;
01254 }
01255 else
01256 {
01257 break;
01258 }
01259 #endif
01260 }
01261 if (zeroes)
01262 flags &= ~NDIGITS;
01263
01264
01265
01266
01267
01268 if (flags & NDIGITS)
01269 {
01270 if (flags & EXPOK)
01271 {
01272
01273
01274 while (p > buf)
01275 {
01276 #ifndef SMALL_SCANF
01277 ungetc (*(u_char *)-- p, fp);
01278 #else
01279 __io_ungetc(*(u_char *)-- p);
01280 #endif
01281 --nread;
01282 }
01283
01284 goto match_failure;
01285
01286 }
01287
01288
01289 c = *(u_char *)-- p;
01290 --nread;
01291 if (c != 'e' && c != 'E')
01292 {
01293 #ifndef SMALL_SCANF
01294 _CAST_VOID ungetc (c, fp);
01295 #else
01296 _CAST_VOID __io_ungetc (c);
01297 #endif
01298 c = *(u_char *)-- p;
01299 --nread;
01300 }
01301 #ifndef SMALL_SCANF
01302 _CAST_VOID ungetc (c, fp);
01303 #else
01304 _CAST_VOID __io_ungetc (c);
01305 #endif
01306
01307 }
01308 if ((flags & SUPPRESS) == 0)
01309 {
01310 double res = 0;
01311 #ifdef _NO_LONGDBL
01312 #define QUAD_RES res;
01313 #else
01314 long double qres = 0;
01315 #define QUAD_RES qres;
01316 #endif
01317 long new_exp = 0;
01318
01319 *p = 0;
01320 if ((flags & (DPTOK | EXPOK)) == EXPOK)
01321 {
01322 exp_adjust = zeroes - leading_zeroes;
01323 new_exp = -exp_adjust;
01324 exp_start = p;
01325 }
01326 else if (exp_adjust)
01327 new_exp = _strtol_r (rptr, (exp_start + 1), NULL, 10) - exp_adjust;
01328 if (exp_adjust)
01329 {
01330
01331
01332
01333 if (exp_start >= buf + sizeof (buf) - MAX_LONG_LEN)
01334 exp_start = buf + sizeof (buf) - MAX_LONG_LEN - 1;
01335 sprintf (exp_start, "e%ld", new_exp);
01336 }
01337
01338
01339
01340
01341 #ifndef _NO_LONGDBL
01342 if (flags & LONGDBL)
01343 qres = _strtold (buf, NULL);
01344 else
01345 #endif
01346 res = _strtod_r (rptr, buf, NULL);
01347 if (flags & LONG)
01348 {
01349 dp = va_arg (ap, double *);
01350 *dp = res;
01351 }
01352 else if (flags & LONGDBL)
01353 {
01354 ldp = va_arg (ap, _LONG_DOUBLE *);
01355 *ldp = QUAD_RES;
01356 }
01357 else
01358 {
01359 flp = va_arg (ap, float *);
01360 *flp = res;
01361 }
01362 nassigned++;
01363 }
01364 break;
01365 }
01366 #endif
01367
01368 }
01369 }
01370 input_failure:
01371 return nassigned ? nassigned : -1;
01372 match_failure:
01373 return nassigned;
01374 }
01375
01376
01377
01378
01379
01380
01381
01382
01383
01384 u_char *
01385 __sccl (tab, fmt)
01386 register char *tab;
01387 register u_char *fmt;
01388 {
01389 register int c, n, v;
01390
01391
01392 c = *fmt++;
01393 if (c == '^')
01394 {
01395 v = 1;
01396 c = *fmt++;
01397 }
01398 else
01399 v = 0;
01400
01401 for (n = 0; n < 256; n++)
01402 tab[n] = v;
01403 if (c == 0)
01404 return fmt - 1;
01405
01406
01407
01408
01409
01410
01411
01412
01413
01414 v = 1 - v;
01415 for (;;)
01416 {
01417 tab[c] = v;
01418 doswitch:
01419 n = *fmt++;
01420 switch (n)
01421 {
01422
01423 case 0:
01424 return fmt - 1;
01425
01426 case '-':
01427
01428
01429
01430
01431
01432
01433
01434
01435
01436
01437
01438
01439 n = *fmt;
01440 if (n == ']' || n < c)
01441 {
01442 c = '-';
01443 break;
01444 }
01445 fmt++;
01446 do
01447 {
01448 tab[++c] = v;
01449 }
01450 while (c < n);
01451 #if 1
01452
01453
01454
01455
01456
01457 goto doswitch;
01458 #else
01459 c = *fmt++;
01460 if (c == 0)
01461 return fmt - 1;
01462 if (c == ']')
01463 return fmt;
01464 #endif
01465
01466 break;
01467
01468
01469 case ']':
01470 return fmt;
01471
01472 default:
01473 c = n;
01474 break;
01475 }
01476 }
01477
01478 }
01479
01480
01481