OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [tags/] [gnu-src/] [newlib-1.18.0/] [newlib-1.18.0-or32-1.0rc1/] [newlib/] [libc/] [stdio/] [vfwscanf.c] - Blame information for rev 345

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 207 jeremybenn
/*-
2
 * Copyright (c) 1990 The Regents of the University of California.
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms are permitted
6
 * provided that the above copyright notice and this paragraph are
7
 * duplicated in all such forms and that any documentation,
8
 * advertising materials, and other materials related to such
9
 * distribution and use acknowledge that the software was developed
10
 * by the University of California, Berkeley.  The name of the
11
 * University may not be used to endorse or promote products derived
12
 * from this software without specific prior written permission.
13
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16
 */
17
 
18
/*
19
FUNCTION
20
<<vfwscanf>>, <<vwscanf>>, <<vswscanf>>---scan and format argument list from wide character input
21
 
22
INDEX
23
        vfwscanf
24
INDEX
25
        _vfwscanf
26
INDEX
27
        vwscanf
28
INDEX
29
        _vwscanf
30
INDEX
31
        vswscanf
32
INDEX
33
        _vswscanf
34
 
35
ANSI_SYNOPSIS
36
        #include <stdio.h>
37
        #include <stdarg.h>
38
        int vwscanf(const wchar_t *<[fmt]>, va_list <[list]>);
39
        int vfwscanf(FILE *<[fp]>, const wchar_t *<[fmt]>, va_list <[list]>);
40
        int vswscanf(const wchar_t *<[str]>, const wchar_t *<[fmt]>, va_list <[list]>);
41
 
42
        int _vwscanf(struct _reent *<[reent]>, const wchar_t *<[fmt]>,
43
                       va_list <[list]>);
44
        int _vfwscanf(struct _reent *<[reent]>, FILE *<[fp]>, const wchar_t *<[fmt]>,
45
                       va_list <[list]>);
46
        int _vswscanf(struct _reent *<[reent]>, const wchar_t *<[str]>,
47
                       const wchar_t *<[fmt]>, va_list <[list]>);
48
 
49
TRAD_SYNOPSIS
50
        #include <stdio.h>
51
        #include <varargs.h>
52
        int vwscanf( <[fmt]>, <[ist]>)
53
        wchar_t *<[fmt]>;
54
        va_list <[list]>;
55
 
56
        int vfwscanf( <[fp]>, <[fmt]>, <[list]>)
57
        FILE *<[fp]>;
58
        wchar_t *<[fmt]>;
59
        va_list <[list]>;
60
 
61
        int vswscanf( <[str]>, <[fmt]>, <[list]>)
62
        wchar_t *<[str]>;
63
        wchar_t *<[fmt]>;
64
        va_list <[list]>;
65
 
66
        int _vwscanf( <[reent]>, <[fmt]>, <[ist]>)
67
        struct _reent *<[reent]>;
68
        wchar_t *<[fmt]>;
69
        va_list <[list]>;
70
 
71
        int _vfwscanf( <[reent]>, <[fp]>, <[fmt]>, <[list]>)
72
        struct _reent *<[reent]>;
73
        FILE *<[fp]>;
74
        wchar_t *<[fmt]>;
75
        va_list <[list]>;
76
 
77
        int _vswscanf( <[reent]>, <[str]>, <[fmt]>, <[list]>)
78
        struct _reent *<[reent]>;
79
        wchar_t *<[str]>;
80
        wchar_t *<[fmt]>;
81
        va_list <[list]>;
82
 
83
DESCRIPTION
84
<<vwscanf>>, <<vfwscanf>>, and <<vswscanf>> are (respectively) variants
85
of <<wscanf>>, <<fwscanf>>, and <<swscanf>>.  They differ only in
86
allowing their caller to pass the variable argument list as a
87
<<va_list>> object (initialized by <<va_start>>) rather than
88
directly accepting a variable number of arguments.
89
 
90
RETURNS
91
The return values are consistent with the corresponding functions:
92
<<vwscanf>> returns the number of input fields successfully scanned,
93
converted, and stored; the return value does not include scanned
94
fields which were not stored.
95
 
96
If <<vwscanf>> attempts to read at end-of-file, the return value
97
is <<EOF>>.
98
 
99
If no fields were stored, the return value is <<0>>.
100
 
101
The routines <<_vwscanf>>, <<_vfwscanf>>, and <<_vswscanf>> are
102
reentrant versions which take an additional first parameter which points
103
to the reentrancy structure.
104
 
105
PORTABILITY
106
C99, POSIX-1.2008
107
*/
108
 
109
#include <_ansi.h>
110
#include <reent.h>
111
#include <newlib.h>
112
#include <ctype.h>
113
#include <wctype.h>
114
#include <stdio.h>
115
#include <stdlib.h>
116
#include <stdint.h>
117
#include <limits.h>
118
#include <wchar.h>
119
#include <string.h>
120
#include <stdarg.h>
121
#include <errno.h>
122
#include "local.h"
123
 
124
#ifdef INTEGER_ONLY
125
#define VFWSCANF vfiwscanf
126
#define _VFWSCANF_R _vfiwscanf_r
127
#define __SVFWSCANF __svfiwscanf
128
#ifdef STRING_ONLY
129
#  define __SVFWSCANF_R __ssvfiwscanf_r
130
#else
131
#  define __SVFWSCANF_R __svfiwscanf_r
132
#endif
133
#else
134
#define VFWSCANF vfwscanf
135
#define _VFWSCANF_R _vfwscanf_r
136
#define __SVFWSCANF __svfwscanf
137
#ifdef STRING_ONLY
138
#  define __SVFWSCANF_R __ssvfwscanf_r
139
#else
140
#  define __SVFWSCANF_R __svfwscanf_r
141
#endif
142
#ifndef NO_FLOATING_POINT
143
#define FLOATING_POINT
144
#endif
145
#endif
146
 
147
#ifdef STRING_ONLY
148
#undef _flockfile
149
#undef _funlockfile
150
#define _flockfile(x) {}
151
#define _funlockfile(x) {}
152
#define _ungetwc_r _sungetwc_r
153
#define __srefill_r __ssrefill_r
154
#define _fgetwc_r _sfgetwc_r
155
#endif
156
 
157
#ifdef FLOATING_POINT
158
#include <math.h>
159
#include <float.h>
160
 
161
/* Currently a test is made to see if long double processing is warranted.
162
   This could be changed in the future should the _ldtoa_r code be
163
   preferred over _dtoa_r.  */
164
#define _NO_LONGDBL
165
#if defined _WANT_IO_LONG_DOUBLE && (LDBL_MANT_DIG > DBL_MANT_DIG)
166
#undef _NO_LONGDBL
167
extern _LONG_DOUBLE _wcstold_r _PARAMS((wchar_t *s, wchar_t **sptr));
168
#endif
169
 
170
#include "floatio.h"
171
 
172
#if ((MAXEXP+MAXFRACT+3) > MB_LEN_MAX)
173
#  define BUF (MAXEXP+MAXFRACT+3)        /* 3 = sign + decimal point + NUL */
174
#else
175
#  define BUF MB_LEN_MAX
176
#endif
177
 
178
/* An upper bound for how long a long prints in decimal.  4 / 13 approximates
179
   log (2).  Add one char for roundoff compensation and one for the sign.  */
180
#define MAX_LONG_LEN ((CHAR_BIT * sizeof (long)  - 1) * 4 / 13 + 2)
181
#else
182
#define BUF     40
183
#endif
184
 
185
#define _NO_LONGLONG
186
#if defined _WANT_IO_LONG_LONG \
187
        && (defined __GNUC__ || __STDC_VERSION__ >= 199901L)
188
# undef _NO_LONGLONG
189
#endif
190
 
191
#define _NO_POS_ARGS
192
#ifdef _WANT_IO_POS_ARGS
193
# undef _NO_POS_ARGS
194
# ifdef NL_ARGMAX
195
#  define MAX_POS_ARGS NL_ARGMAX
196
# else
197
#  define MAX_POS_ARGS 32
198
# endif
199
 
200
static void * get_arg (int, va_list *, int *, void **);
201
#endif /* _WANT_IO_POS_ARGS */
202
 
203
/*
204
 * Flags used during conversion.
205
 */
206
 
207
#define LONG            0x01    /* l: long or double */
208
#define LONGDBL         0x02    /* L/ll: long double or long long */
209
#define SHORT           0x04    /* h: short */
210
#define CHAR            0x08    /* hh: 8 bit integer */
211
#define SUPPRESS        0x10    /* suppress assignment */
212
#define POINTER         0x20    /* weird %p pointer (`fake hex') */
213
#define NOSKIP          0x40    /* do not skip blanks */
214
 
215
/*
216
 * The following are used in numeric conversions only:
217
 * SIGNOK, NDIGITS, DPTOK, and EXPOK are for floating point;
218
 * SIGNOK, NDIGITS, PFXOK, and NZDIGITS are for integral.
219
 */
220
 
221
#define SIGNOK          0x80    /* +/- is (still) legal */
222
#define NDIGITS         0x100   /* no digits detected */
223
 
224
#define DPTOK           0x200   /* (float) decimal point is still legal */
225
#define EXPOK           0x400   /* (float) exponent (e+3, etc) still legal */
226
 
227
#define PFXOK           0x200   /* 0x prefix is (still) legal */
228
#define NZDIGITS        0x400   /* no zero digits detected */
229
#define HAVESIGN        0x10000 /* sign detected */
230
 
231
/*
232
 * Conversion types.
233
 */
234
 
235
#define CT_CHAR         0        /* %c conversion */
236
#define CT_CCL          1       /* %[...] conversion */
237
#define CT_STRING       2       /* %s conversion */
238
#define CT_INT          3       /* integer, i.e., wcstol or wcstoul */
239
#define CT_FLOAT        4       /* floating, i.e., wcstod */
240
 
241
#define INCCL(_c)       \
242
        (cclcompl ? (wmemchr(ccls, (_c), ccle - ccls) == NULL) : \
243
        (wmemchr(ccls, (_c), ccle - ccls) != NULL))
244
 
245
/*
246
 * vfwscanf
247
 */
248
 
249
#ifndef STRING_ONLY
250
 
251
#ifndef _REENT_ONLY
252
 
253
int
254
_DEFUN(VFWSCANF, (fp, fmt, ap),
255
       register FILE *fp _AND
256
       _CONST wchar_t *fmt _AND
257
       va_list ap)
258
{
259
  CHECK_INIT(_REENT, fp);
260
  return __SVFWSCANF_R (_REENT, fp, fmt, ap);
261
}
262
 
263
int
264
_DEFUN(__SVFWSCANF, (fp, fmt0, ap),
265
       register FILE *fp _AND
266
       wchar_t _CONST *fmt0 _AND
267
       va_list ap)
268
{
269
  return __SVFWSCANF_R (_REENT, fp, fmt0, ap);
270
}
271
 
272
#endif /* !_REENT_ONLY */
273
 
274
int
275
_DEFUN(_VFWSCANF_R, (data, fp, fmt, ap),
276
       struct _reent *data _AND
277
       register FILE *fp   _AND
278
       _CONST wchar_t *fmt    _AND
279
       va_list ap)
280
{
281
  CHECK_INIT(data, fp);
282
  return __SVFWSCANF_R (data, fp, fmt, ap);
283
}
284
#endif /* !STRING_ONLY */
285
 
286
#ifdef STRING_ONLY
287
/* When dealing with the swscanf family, we don't want to use the
288
 * regular ungetwc which will drag in file I/O items we don't need.
289
 * So, we create our own trimmed-down version.  */
290
static wint_t
291
_DEFUN(_sungetwc_r, (data, fp, ch),
292
        struct _reent *data _AND
293
        wint_t wc           _AND
294
        register FILE *fp)
295
{
296
  if (wc == WEOF)
297
    return (WEOF);
298
 
299
  /* After ungetc, we won't be at eof anymore */
300
  fp->_flags &= ~__SEOF;
301
 
302
  /*
303
   * If we are in the middle of ungetwc'ing, just continue.
304
   * This may require expanding the current ungetc buffer.
305
   */
306
 
307
  if (HASUB (fp))
308
    {
309
      if (fp->_r >= fp->_ub._size && __submore (data, fp))
310
        {
311
          return EOF;
312
        }
313
      fp->_p -= sizeof (wchar_t);
314
      *fp->_p = (wchar_t) wc;
315
      fp->_r += sizeof (wchar_t);
316
      return wc;
317
    }
318
 
319
  /*
320
   * If we can handle this by simply backing up, do so,
321
   * but never replace the original character.
322
   * (This makes swscanf() work when scanning `const' data.)
323
   */
324
 
325
  if (fp->_bf._base != NULL && fp->_p > fp->_bf._base
326
      && ((wchar_t *)fp->_p)[-1] == wc)
327
    {
328
      fp->_p -= sizeof (wchar_t);
329
      fp->_r += sizeof (wchar_t);
330
      return wc;
331
    }
332
 
333
  /*
334
   * Create an ungetc buffer.
335
   * Initially, we will use the `reserve' buffer.
336
   */
337
 
338
  fp->_ur = fp->_r;
339
  fp->_up = fp->_p;
340
  fp->_ub._base = fp->_ubuf;
341
  fp->_ub._size = sizeof (fp->_ubuf);
342
  fp->_p = &fp->_ubuf[sizeof (fp->_ubuf) - sizeof (wchar_t)];
343
  *(wchar_t *) fp->_p = wc;
344
  fp->_r = 2;
345
  return wc;
346
}
347
 
348
extern int __ssrefill_r _PARAMS ((struct _reent *ptr, register FILE * fp));
349
 
350
static size_t
351
_DEFUN(_sfgetwc_r, (ptr, fp),
352
       struct _reent * ptr _AND
353
       FILE * fp)
354
{
355
  wchar_t wc;
356
 
357
  if (fp->_r <= 0 && __ssrefill_r (ptr, fp))
358
    return (WEOF);
359
  wc = *(wchar_t *) fp->_p;
360
  fp->_p += sizeof (wchar_t);
361
  fp->_r -= sizeof (wchar_t);
362
  return (wc);
363
}
364
#endif /* STRING_ONLY */
365
 
366
int
367
_DEFUN(__SVFWSCANF_R, (rptr, fp, fmt0, ap),
368
       struct _reent *rptr _AND
369
       register FILE *fp   _AND
370
       wchar_t _CONST *fmt0   _AND
371
       va_list ap)
372
{
373
  register wchar_t *fmt = (wchar_t *) fmt0;
374
  register wint_t c;            /* character from format, or conversion */
375
  register size_t width;        /* field width, or 0 */
376
  register wchar_t *p = NULL;   /* points into all kinds of strings */
377
  register int n;               /* handy integer */
378
  register int flags;           /* flags as defined above */
379
  register wchar_t *p0;         /* saves original value of p when necessary */
380
  int nassigned;                /* number of fields assigned */
381
  int nread;                    /* number of characters consumed from fp */
382
#ifndef _NO_POS_ARGS
383
  int N;                        /* arg number */
384
  int arg_index = 0;             /* index into args processed directly */
385
  int numargs = 0;               /* number of varargs read */
386
  void *args[MAX_POS_ARGS];     /* positional args read */
387
  int is_pos_arg;               /* is current format positional? */
388
#endif
389
  int base = 0;                  /* base argument to wcstol/wcstoul */
390
 
391
  mbstate_t mbs;                /* value to keep track of multibyte state */
392
 
393
  #define CCFN_PARAMS   _PARAMS((struct _reent *, const wchar_t *, wchar_t **, int))
394
  unsigned long (*ccfn)CCFN_PARAMS=0;    /* conversion function (wcstol/wcstoul) */
395
  wchar_t buf[BUF];             /* buffer for numeric conversions */
396
  const wchar_t *ccls;          /* character class start */
397
  const wchar_t *ccle;          /* character class end */
398
  int cclcompl = 0;             /* ccl is complemented? */
399
  wint_t wi;                    /* handy wint_t */
400
  char *mbp = NULL;             /* multibyte string pointer for %c %s %[ */
401
  size_t nconv;                 /* number of bytes in mb. conversion */
402
  char mbbuf[MB_LEN_MAX];       /* temporary mb. character buffer */
403
 
404
  char *cp;
405
  short *sp;
406
  int *ip;
407
#ifdef FLOATING_POINT
408
  float *flp;
409
  _LONG_DOUBLE *ldp;
410
  double *dp;
411
#endif
412
  long *lp;
413
#ifndef _NO_LONGLONG
414
  long long *llp;
415
#endif
416
 
417
  /* `basefix' is used to avoid `if' tests in the integer scanner */
418
  static _CONST short basefix[17] =
419
    {10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
420
 
421
  /* Macro to support positional arguments */
422
#ifndef _NO_POS_ARGS
423
# define GET_ARG(n, ap, type)                                   \
424
  ((type) (is_pos_arg                                           \
425
           ? (n < numargs                                       \
426
              ? args[n]                                         \
427
              : get_arg (n, &ap, &numargs, args))               \
428
           : (arg_index++ < numargs                             \
429
              ? args[n]                                         \
430
              : (numargs < MAX_POS_ARGS                         \
431
                 ? args[numargs++] = va_arg (ap, void *)        \
432
                 : va_arg (ap, void *)))))
433
#else
434
# define GET_ARG(n, ap, type) (va_arg (ap, type))
435
#endif
436
 
437
  __sfp_lock_acquire ();
438
  _flockfile (fp);
439
 
440
  ORIENT (fp, 1);
441
 
442
  nassigned = 0;
443
  nread = 0;
444
  ccls = ccle = NULL;
445
  for (;;)
446
    {
447
      c = *fmt++;
448
      if (c == L'\0')
449
        goto all_done;
450
      if (iswspace (c))
451
        {
452
          while ((c = _fgetwc_r (rptr, fp)) != WEOF && iswspace(c))
453
            ;
454
          if (c != WEOF)
455
            _ungetwc_r (rptr, c, fp);
456
          continue;
457
        }
458
      if (c != L'%')
459
        goto literal;
460
      width = 0;
461
      flags = 0;
462
#ifndef _NO_POS_ARGS
463
      N = arg_index;
464
      is_pos_arg = 0;
465
#endif
466
 
467
      /*
468
       * switch on the format.  continue if done; break once format
469
       * type is derived.
470
       */
471
 
472
    again:
473
      c = *fmt++;
474
 
475
      switch (c)
476
        {
477
        case L'%':
478
        literal:
479
          if ((wi = _fgetwc_r (rptr, fp)) == WEOF)
480
            goto input_failure;
481
          if (wi != c)
482
            {
483
              _ungetwc_r (rptr, wi, fp);
484
              goto input_failure;
485
            }
486
          nread++;
487
          continue;
488
 
489
        case L'*':
490
          flags |= SUPPRESS;
491
          goto again;
492
        case L'l':
493
#if defined _WANT_IO_C99_FORMATS || !defined _NO_LONGLONG
494
          if (*fmt == L'l')     /* Check for 'll' = long long (SUSv3) */
495
            {
496
              ++fmt;
497
              flags |= LONGDBL;
498
            }
499
          else
500
#endif
501
            flags |= LONG;
502
          goto again;
503
        case L'L':
504
          flags |= LONGDBL;
505
          goto again;
506
        case L'h':
507
#ifdef _WANT_IO_C99_FORMATS
508
          if (*fmt == 'h')      /* Check for 'hh' = char int (SUSv3) */
509
            {
510
              ++fmt;
511
              flags |= CHAR;
512
            }
513
          else
514
#endif
515
            flags |= SHORT;
516
          goto again;
517
#ifdef _WANT_IO_C99_FORMATS
518
        case L'j': /* intmax_t */
519
          if (sizeof (intmax_t) == sizeof (long))
520
            flags |= LONG;
521
          else
522
            flags |= LONGDBL;
523
          goto again;
524
        case L't': /* ptrdiff_t */
525
          if (sizeof (ptrdiff_t) < sizeof (int))
526
            /* POSIX states ptrdiff_t is 16 or more bits, as
527
               is short.  */
528
            flags |= SHORT;
529
          else if (sizeof (ptrdiff_t) == sizeof (int))
530
            /* no flag needed */;
531
          else if (sizeof (ptrdiff_t) <= sizeof (long))
532
            flags |= LONG;
533
          else
534
            /* POSIX states that at least one programming
535
               environment must support ptrdiff_t no wider than
536
               long, but that means other environments can
537
               have ptrdiff_t as wide as long long.  */
538
            flags |= LONGDBL;
539
          goto again;
540
        case L'z': /* size_t */
541
          if (sizeof (size_t) < sizeof (int))
542
            /* POSIX states size_t is 16 or more bits, as is short.  */
543
            flags |= SHORT;
544
          else if (sizeof (size_t) == sizeof (int))
545
            /* no flag needed */;
546
          else if (sizeof (size_t) <= sizeof (long))
547
            flags |= LONG;
548
          else
549
            /* POSIX states that at least one programming
550
               environment must support size_t no wider than
551
               long, but that means other environments can
552
               have size_t as wide as long long.  */
553
            flags |= LONGDBL;
554
          goto again;
555
#endif /* _WANT_IO_C99_FORMATS */
556
 
557
        case L'0':
558
        case L'1':
559
        case L'2':
560
        case L'3':
561
        case L'4':
562
        case L'5':
563
        case L'6':
564
        case L'7':
565
        case L'8':
566
        case L'9':
567
          width = width * 10 + c - L'0';
568
          goto again;
569
 
570
#ifndef _NO_POS_ARGS
571
        case L'$':
572
          if (width <= MAX_POS_ARGS)
573
            {
574
              N = width - 1;
575
              is_pos_arg = 1;
576
              width = 0;
577
              goto again;
578
            }
579
          rptr->_errno = EINVAL;
580
          goto input_failure;
581
#endif /* !_NO_POS_ARGS */
582
 
583
        case L'd':
584
          c = CT_INT;
585
          ccfn = (unsigned long (*)CCFN_PARAMS)_wcstol_r;
586
          base = 10;
587
          break;
588
 
589
        case L'i':
590
          c = CT_INT;
591
          ccfn = (unsigned long (*)CCFN_PARAMS)_wcstol_r;
592
          base = 0;
593
          break;
594
 
595
        case L'o':
596
          c = CT_INT;
597
          ccfn = _wcstoul_r;
598
          base = 8;
599
          break;
600
 
601
        case L'u':
602
          c = CT_INT;
603
          ccfn = _wcstoul_r;
604
          base = 10;
605
          break;
606
 
607
        case L'X':
608
        case L'x':
609
          flags |= PFXOK;       /* enable 0x prefixing */
610
          c = CT_INT;
611
          ccfn = _wcstoul_r;
612
          base = 16;
613
          break;
614
 
615
#ifdef FLOATING_POINT
616
# ifdef _WANT_IO_C99_FORMATS
617
        case L'A':
618
        case L'a':
619
        case L'F':
620
# endif
621
        case L'E':
622
        case L'G':
623
        case L'e':
624
        case L'f':
625
        case L'g':
626
          c = CT_FLOAT;
627
          break;
628
#endif
629
 
630
#ifdef _WANT_IO_C99_FORMATS
631
        case L'S':
632
          flags |= LONG;
633
          /* FALLTHROUGH */
634
#endif
635
 
636
        case L's':
637
          c = CT_STRING;
638
          break;
639
 
640
        case L'[':
641
          ccls = fmt;
642
          if (*fmt == '^')
643
            {
644
              cclcompl = 1;
645
              ++fmt;
646
            }
647
          else
648
            cclcompl = 0;
649
          if (*fmt == ']')
650
            fmt++;
651
          while (*fmt != '\0' && *fmt != ']')
652
            fmt++;
653
          ccle = fmt;
654
          fmt++;
655
          flags |= NOSKIP;
656
          c = CT_CCL;
657
          break;
658
 
659
#ifdef _WANT_IO_C99_FORMATS
660
        case 'C':
661
          flags |= LONG;
662
          /* FALLTHROUGH */
663
#endif
664
 
665
        case 'c':
666
          flags |= NOSKIP;
667
          c = CT_CHAR;
668
          break;
669
 
670
        case 'p':               /* pointer format is like hex */
671
          flags |= POINTER | PFXOK;
672
          c = CT_INT;
673
          ccfn = _wcstoul_r;
674
          base = 16;
675
          break;
676
 
677
        case 'n':
678
          if (flags & SUPPRESS) /* ??? */
679
            continue;
680
#ifdef _WANT_IO_C99_FORMATS
681
          if (flags & CHAR)
682
            {
683
              cp = GET_ARG (N, ap, char *);
684
              *cp = nread;
685
            }
686
          else
687
#endif
688
          if (flags & SHORT)
689
            {
690
              sp = GET_ARG (N, ap, short *);
691
              *sp = nread;
692
            }
693
          else if (flags & LONG)
694
            {
695
              lp = GET_ARG (N, ap, long *);
696
              *lp = nread;
697
            }
698
#ifndef _NO_LONGLONG
699
          else if (flags & LONGDBL)
700
            {
701
              llp = GET_ARG (N, ap, long long*);
702
              *llp = nread;
703
            }
704
#endif
705
          else
706
            {
707
              ip = GET_ARG (N, ap, int *);
708
              *ip = nread;
709
            }
710
          continue;
711
 
712
          /*
713
           * Disgusting backwards compatibility hacks.  XXX
714
           */
715
        case L'\0':             /* compat */
716
          _funlockfile (fp);
717
          __sfp_lock_release ();
718
          return EOF;
719
 
720
        default:                /* compat */
721
          goto match_failure;
722
        }
723
 
724
      /*
725
       * Consume leading white space, except for formats that
726
       * suppress this.
727
       */
728
      if ((flags & NOSKIP) == 0)
729
        {
730
          while ((wi = _fgetwc_r (rptr, fp)) != WEOF && iswspace (wi))
731
            nread++;
732
          if (wi == WEOF)
733
            goto input_failure;
734
          _ungetwc_r (rptr, wi, fp);
735
        }
736
 
737
      /*
738
       * Do the conversion.
739
       */
740
      switch (c)
741
        {
742
 
743
        case CT_CHAR:
744
          /* scan arbitrary characters (sets NOSKIP) */
745
          if (width == 0)
746
            width = 1;
747
          if (flags & LONG)
748
            {
749
              if (!(flags & SUPPRESS))
750
                p = va_arg(ap, wchar_t *);
751
              n = 0;
752
              while (width-- != 0 && (wi = _fgetwc_r (rptr, fp)) != WEOF)
753
                {
754
                  if (!(flags & SUPPRESS))
755
                    *p++ = (wchar_t) wi;
756
                  n++;
757
                }
758
              if (n == 0)
759
                goto input_failure;
760
              nread += n;
761
              if (!(flags & SUPPRESS))
762
                nassigned++;
763
            }
764
          else
765
            {
766
              if (!(flags & SUPPRESS))
767
                mbp = va_arg(ap, char *);
768
              n = 0;
769
              memset ((_PTR)&mbs, '\0', sizeof (mbstate_t));
770
              while (width != 0 && (wi = _fgetwc_r (rptr, fp)) != WEOF)
771
                {
772
                  if (width >= MB_CUR_MAX && !(flags & SUPPRESS))
773
                    {
774
                      nconv = _wcrtomb_r (rptr, mbp, wi, &mbs);
775
                      if (nconv == (size_t) -1)
776
                        goto input_failure;
777
                    }
778
                  else
779
                    {
780
                      nconv = _wcrtomb_r (rptr, mbbuf, wi, &mbs);
781
                      if (nconv == (size_t) -1)
782
                        goto input_failure;
783
                      if (nconv > width)
784
                        {
785
                          _ungetwc_r (rptr, wi, fp);
786
                          break;
787
                        }
788
                      if (!(flags & SUPPRESS))
789
                        memcpy(mbp, mbbuf, nconv);
790
                    }
791
                  if (!(flags & SUPPRESS))
792
                    mbp += nconv;
793
                  width -= nconv;
794
                  n++;
795
                }
796
              if (n == 0)
797
                goto input_failure;
798
              nread += n;
799
              if (!(flags & SUPPRESS))
800
                nassigned++;
801
            }
802
          break;
803
 
804
        case CT_CCL:
805
          /* scan a (nonempty) character class (sets NOSKIP) */
806
          if (width == 0)
807
            width = (size_t) ~0;         /* `infinity' */
808
          /* take only those things in the class */
809
          if ((flags & SUPPRESS) && (flags & LONG))
810
            {
811
              n = 0;
812
              while ((wi = _fgetwc_r (rptr, fp)) != WEOF
813
                     && width-- != 0 && INCCL (wi))
814
                n++;
815
              if (wi != WEOF)
816
                _ungetwc_r (rptr, wi, fp);
817
              if (n == 0)
818
                goto match_failure;
819
            }
820
          else if (flags & LONG)
821
            {
822
              p0 = p = va_arg(ap, wchar_t *);
823
              while ((wi = _fgetwc_r (rptr, fp)) != WEOF
824
                     && width-- != 0 && INCCL (wi))
825
                *p++ = (wchar_t) wi;
826
              if (wi != WEOF)
827
                _ungetwc_r (rptr, wi, fp);
828
              n = p - p0;
829
              if (n == 0)
830
                goto match_failure;
831
            }
832
          else
833
            {
834
              if (!(flags & SUPPRESS))
835
                mbp = va_arg(ap, char *);
836
              n = 0;
837
              memset ((_PTR) &mbs, '\0', sizeof (mbstate_t));
838
              while ((wi = _fgetwc_r (rptr, fp)) != WEOF
839
                     && width-- != 0 && INCCL (wi))
840
                {
841
                  if (width >= MB_CUR_MAX && !(flags & SUPPRESS))
842
                    {
843
                      nconv = _wcrtomb_r (rptr, mbp, wi, &mbs);
844
                      if (nconv == (size_t) -1)
845
                        goto input_failure;
846
                    }
847
                  else
848
                    {
849
                      nconv = wcrtomb(mbbuf, wi, &mbs);
850
                      if (nconv == (size_t) -1)
851
                        goto input_failure;
852
                      if (nconv > width)
853
                        break;
854
                      if (!(flags & SUPPRESS))
855
                        memcpy(mbp, mbbuf, nconv);
856
                    }
857
                  if (!(flags & SUPPRESS))
858
                    mbp += nconv;
859
                  width -= nconv;
860
                  n++;
861
                }
862
              if (wi != WEOF)
863
                _ungetwc_r (rptr, wi, fp);
864
              if (!(flags & SUPPRESS))
865
                {
866
                  *mbp = 0;
867
                  nassigned++;
868
                }
869
            }
870
          nread += n;
871
          break;
872
 
873
        case CT_STRING:
874
          /* like CCL, but zero-length string OK, & no NOSKIP */
875
          if (width == 0)
876
            width = (size_t)~0;
877
          if ((flags & SUPPRESS) && (flags & LONG))
878
            {
879
              while ((wi = _fgetwc_r (rptr, fp)) != WEOF
880
                     && width-- != 0 && !iswspace (wi))
881
                nread++;
882
              if (wi != WEOF)
883
                _ungetwc_r (rptr, wi, fp);
884
            }
885
          else if (flags & LONG)
886
            {
887
              p0 = p = va_arg(ap, wchar_t *);
888
              while ((wi = _fgetwc_r (rptr, fp)) != WEOF
889
                     && width-- != 0 && !iswspace (wi))
890
                {
891
                  *p++ = (wchar_t) wi;
892
                  nread++;
893
                }
894
              if (wi != WEOF)
895
                _ungetwc_r (rptr, wi, fp);
896
              *p = '\0';
897
              nassigned++;
898
            }
899
          else
900
            {
901
              if (!(flags & SUPPRESS))
902
                mbp = va_arg(ap, char *);
903
              memset ((_PTR) &mbs, '\0', sizeof (mbstate_t));
904
              while ((wi = _fgetwc_r (rptr, fp)) != WEOF
905
                     && width != 0 && !iswspace (wi))
906
                {
907
                  if (width >= MB_CUR_MAX && !(flags & SUPPRESS))
908
                    {
909
                      nconv = wcrtomb(mbp, wi, &mbs);
910
                      if (nconv == (size_t)-1)
911
                        goto input_failure;
912
                    }
913
                  else
914
                    {
915
                      nconv = wcrtomb(mbbuf, wi, &mbs);
916
                      if (nconv == (size_t)-1)
917
                        goto input_failure;
918
                      if (nconv > width)
919
                        break;
920
                      if (!(flags & SUPPRESS))
921
                        memcpy(mbp, mbbuf, nconv);
922
                    }
923
                  if (!(flags & SUPPRESS))
924
                    mbp += nconv;
925
                  width -= nconv;
926
                  nread++;
927
                }
928
              if (wi != WEOF)
929
                _ungetwc_r (rptr, wi, fp);
930
              if (!(flags & SUPPRESS))
931
                {
932
                  *mbp = 0;
933
                  nassigned++;
934
                }
935
            }
936
          continue;
937
 
938
        case CT_INT:
939
        {
940
          /* scan an integer as if by wcstol/wcstoul */
941
          if (width == 0 || width > sizeof (buf) / sizeof (*buf) - 1)
942
            width = sizeof(buf) / sizeof (*buf) - 1;
943
          flags |= SIGNOK | NDIGITS | NZDIGITS;
944
          for (p = buf; width; width--)
945
            {
946
              c = _fgetwc_r (rptr, fp);
947
              /*
948
               * Switch on the character; `goto ok' if we
949
               * accept it as a part of number.
950
               */
951
              switch (c)
952
                {
953
                  /*
954
                   * The digit 0 is always legal, but is special.
955
                   * For %i conversions, if no digits (zero or nonzero)
956
                   * have been scanned (only signs), we will have base==0.
957
                   * In that case, we should set it to 8 and enable 0x
958
                   * prefixing. Also, if we have not scanned zero digits
959
                   * before this, do not turn off prefixing (someone else
960
                   * will turn it off if we have scanned any nonzero digits).
961
                   */
962
                case L'0':
963
                  if (base == 0)
964
                    {
965
                      base = 8;
966
                      flags |= PFXOK;
967
                    }
968
                  if (flags & NZDIGITS)
969
                    flags &= ~(SIGNOK | NZDIGITS | NDIGITS);
970
                  else
971
                    flags &= ~(SIGNOK | PFXOK | NDIGITS);
972
                  goto ok;
973
 
974
                  /* 1 through 7 always legal */
975
                case L'1':
976
                case L'2':
977
                case L'3':
978
                case L'4':
979
                case L'5':
980
                case L'6':
981
                case L'7':
982
                  base = basefix[base];
983
                  flags &= ~(SIGNOK | PFXOK | NDIGITS);
984
                  goto ok;
985
 
986
                  /* digits 8 and 9 ok iff decimal or hex */
987
                case L'8':
988
                case L'9':
989
                  base = basefix[base];
990
                  if (base <= 8)
991
                    break;      /* not legal here */
992
                  flags &= ~(SIGNOK | PFXOK | NDIGITS);
993
                  goto ok;
994
 
995
                  /* letters ok iff hex */
996
                case L'A':
997
                case L'B':
998
                case L'C':
999
                case L'D':
1000
                case L'E':
1001
                case L'F':
1002
                case L'a':
1003
                case L'b':
1004
                case L'c':
1005
                case L'd':
1006
                case L'e':
1007
                case L'f':
1008
                  /* no need to fix base here */
1009
                  if (base <= 10)
1010
                    break;      /* not legal here */
1011
                  flags &= ~(SIGNOK | PFXOK | NDIGITS);
1012
                  goto ok;
1013
 
1014
                  /* sign ok only as first character */
1015
                case L'+':
1016
                case L'-':
1017
                  if (flags & SIGNOK)
1018
                    {
1019
                      flags &= ~SIGNOK;
1020
                      flags |= HAVESIGN;
1021
                      goto ok;
1022
                    }
1023
                  break;
1024
 
1025
                  /* x ok iff flag still set & single 0 seen */
1026
                case L'x':
1027
                case L'X':
1028
                  if ((flags & PFXOK) && p == buf + 1 + !!(flags & HAVESIGN))
1029
                    {
1030
                      base = 16;/* if %i */
1031
                      flags &= ~PFXOK;
1032
                      goto ok;
1033
                    }
1034
                  break;
1035
                }
1036
 
1037
              /*
1038
               * If we got here, c is not a legal character
1039
               * for a number.  Stop accumulating digits.
1040
               */
1041
              if (c != WEOF)
1042
                _ungetwc_r (rptr, c, fp);
1043
              break;
1044
            ok:
1045
              /*
1046
               * c is legal: store it and look at the next.
1047
               */
1048
              *p++ = (wchar_t) c;
1049
            }
1050
          /*
1051
           * If we had only a sign, it is no good; push back the sign.
1052
           * If the number ends in `x', it was [sign] '0' 'x', so push back
1053
           * the x and treat it as [sign] '0'.
1054
           * Use of ungetc here and below assumes ASCII encoding; we are only
1055
           * pushing back 7-bit characters, so casting to unsigned char is
1056
           * not necessary.
1057
           */
1058
          if (flags & NDIGITS)
1059
            {
1060
              if (p > buf)
1061
                _ungetwc_r (rptr, *--p, fp); /* [-+xX] */
1062
              goto match_failure;
1063
            }
1064
          c = p[-1];
1065
          if (c == L'x' || c == L'X')
1066
            {
1067
              --p;
1068
              _ungetwc_r (rptr, c, fp);
1069
            }
1070
          if ((flags & SUPPRESS) == 0)
1071
            {
1072
              unsigned long res;
1073
 
1074
              *p = 0;
1075
              res = (*ccfn) (rptr, buf, (wchar_t **) NULL, base);
1076
              if (flags & POINTER)
1077
                {
1078
                  void **vp = GET_ARG (N, ap, void **);
1079
#ifndef _NO_LONGLONG
1080
                  if (sizeof (uintptr_t) > sizeof (unsigned long))
1081
                    {
1082
                      unsigned long long resll;
1083
                      resll = _wcstoull_r (rptr, buf, (wchar_t **) NULL, base);
1084
                      *vp = (void *) (uintptr_t) resll;
1085
                    }
1086
                  else
1087
#endif /* !_NO_LONGLONG */
1088
                    *vp = (void *) (uintptr_t) res;
1089
                }
1090
#ifdef _WANT_IO_C99_FORMATS
1091
              else if (flags & CHAR)
1092
                {
1093
                  cp = GET_ARG (N, ap, char *);
1094
                  *cp = res;
1095
                }
1096
#endif
1097
              else if (flags & SHORT)
1098
                {
1099
                  sp = GET_ARG (N, ap, short *);
1100
                  *sp = res;
1101
                }
1102
              else if (flags & LONG)
1103
                {
1104
                  lp = GET_ARG (N, ap, long *);
1105
                  *lp = res;
1106
                }
1107
#ifndef _NO_LONGLONG
1108
              else if (flags & LONGDBL)
1109
                {
1110
                  unsigned long long resll;
1111
                  if (ccfn == _wcstoul_r)
1112
                    resll = _wcstoull_r (rptr, buf, (wchar_t **) NULL, base);
1113
                  else
1114
                    resll = _wcstoll_r (rptr, buf, (wchar_t **) NULL, base);
1115
                  llp = GET_ARG (N, ap, long long*);
1116
                  *llp = resll;
1117
                }
1118
#endif
1119
              else
1120
                {
1121
                  ip = GET_ARG (N, ap, int *);
1122
                  *ip = res;
1123
                }
1124
              nassigned++;
1125
            }
1126
          nread += p - buf;
1127
          break;
1128
        }
1129
#ifdef FLOATING_POINT
1130
        case CT_FLOAT:
1131
        {
1132
          /* scan a floating point number as if by wcstod */
1133
          /* This code used to assume that the number of digits is reasonable.
1134
             However, ANSI / ISO C makes no such stipulation; we have to get
1135
             exact results even when there is an unreasonable amount of
1136
             leading zeroes.  */
1137
          long leading_zeroes = 0;
1138
          long zeroes, exp_adjust;
1139
          wchar_t *exp_start = NULL;
1140
          unsigned width_left = 0;
1141
          char nancount = 0;
1142
          char infcount = 0;
1143
#ifdef hardway
1144
          if (width == 0 || width > sizeof (buf) - 1)
1145
#else
1146
          /* size_t is unsigned, hence this optimisation */
1147
          if (width - 1 > sizeof (buf) - 2)
1148
#endif
1149
            {
1150
              width_left = width - (sizeof (buf) - 1);
1151
              width = sizeof (buf) - 1;
1152
            }
1153
          flags |= SIGNOK | NDIGITS | DPTOK | EXPOK;
1154
          zeroes = 0;
1155
          exp_adjust = 0;
1156
          for (p = buf; width; )
1157
            {
1158
              c = _fgetwc_r (rptr, fp);
1159
              /*
1160
               * This code mimicks the integer conversion
1161
               * code, but is much simpler.
1162
               */
1163
              switch (c)
1164
                {
1165
                case L'0':
1166
                  if (flags & NDIGITS)
1167
                    {
1168
                      flags &= ~SIGNOK;
1169
                      zeroes++;
1170
                      if (width_left)
1171
                        {
1172
                          width_left--;
1173
                          width++;
1174
                        }
1175
                      goto fskip;
1176
                    }
1177
                  /* Fall through.  */
1178
                case L'1':
1179
                case L'2':
1180
                case L'3':
1181
                case L'4':
1182
                case L'5':
1183
                case L'6':
1184
                case L'7':
1185
                case L'8':
1186
                case L'9':
1187
                  if (nancount + infcount == 0)
1188
                    {
1189
                      flags &= ~(SIGNOK | NDIGITS);
1190
                      goto fok;
1191
                    }
1192
                  break;
1193
 
1194
                case L'+':
1195
                case L'-':
1196
                  if (flags & SIGNOK)
1197
                    {
1198
                      flags &= ~SIGNOK;
1199
                      goto fok;
1200
                    }
1201
                  break;
1202
                case L'n':
1203
                case L'N':
1204
                  if (nancount == 0 && zeroes == 0
1205
                      && (flags & (NDIGITS | DPTOK | EXPOK)) ==
1206
                                  (NDIGITS | DPTOK | EXPOK))
1207
                    {
1208
                      flags &= ~(SIGNOK | DPTOK | EXPOK | NDIGITS);
1209
                      nancount = 1;
1210
                      goto fok;
1211
                    }
1212
                  if (nancount == 2)
1213
                    {
1214
                      nancount = 3;
1215
                      goto fok;
1216
                    }
1217
                  if (infcount == 1 || infcount == 4)
1218
                    {
1219
                      infcount++;
1220
                      goto fok;
1221
                    }
1222
                  break;
1223
                case L'a':
1224
                case L'A':
1225
                  if (nancount == 1)
1226
                    {
1227
                      nancount = 2;
1228
                      goto fok;
1229
                    }
1230
                  break;
1231
                case L'i':
1232
                  if (infcount == 0 && zeroes == 0
1233
                      && (flags & (NDIGITS | DPTOK | EXPOK)) ==
1234
                                  (NDIGITS | DPTOK | EXPOK))
1235
                    {
1236
                      flags &= ~(SIGNOK | DPTOK | EXPOK | NDIGITS);
1237
                      infcount = 1;
1238
                      goto fok;
1239
                    }
1240
                  if (infcount == 3 || infcount == 5)
1241
                    {
1242
                      infcount++;
1243
                      goto fok;
1244
                    }
1245
                  break;
1246
                case L'f':
1247
                case L'F':
1248
                  if (infcount == 2)
1249
                    {
1250
                      infcount = 3;
1251
                      goto fok;
1252
                    }
1253
                  break;
1254
                case L't':
1255
                case L'T':
1256
                  if (infcount == 6)
1257
                    {
1258
                      infcount = 7;
1259
                      goto fok;
1260
                    }
1261
                  break;
1262
                case L'y':
1263
                case L'Y':
1264
                  if (infcount == 7)
1265
                    {
1266
                      infcount = 8;
1267
                      goto fok;
1268
                    }
1269
                  break;
1270
                case L'.':
1271
                  if (flags & DPTOK)
1272
                    {
1273
                      flags &= ~(SIGNOK | DPTOK);
1274
                      leading_zeroes = zeroes;
1275
                      goto fok;
1276
                    }
1277
                  break;
1278
                case L'e':
1279
                case L'E':
1280
                  /* no exponent without some digits */
1281
                  if ((flags & (NDIGITS | EXPOK)) == EXPOK
1282
                      || ((flags & EXPOK) && zeroes))
1283
                    {
1284
                      if (! (flags & DPTOK))
1285
                        {
1286
                          exp_adjust = zeroes - leading_zeroes;
1287
                          exp_start = p;
1288
                        }
1289
                      flags =
1290
                        (flags & ~(EXPOK | DPTOK)) |
1291
                        SIGNOK | NDIGITS;
1292
                      zeroes = 0;
1293
                      goto fok;
1294
                    }
1295
                  break;
1296
                }
1297
              if (c != WEOF)
1298
                _ungetwc_r (rptr, c, fp);
1299
              break;
1300
            fok:
1301
              *p++ = c;
1302
            fskip:
1303
              width--;
1304
              ++nread;
1305
            }
1306
          if (zeroes)
1307
            flags &= ~NDIGITS;
1308
          /* We may have a 'N' or possibly even [sign] 'N' 'a' as the
1309
             start of 'NaN', only to run out of chars before it was
1310
             complete (or having encountered a non-matching char).  So
1311
             check here if we have an outstanding nancount, and if so
1312
             put back the chars we did swallow and treat as a failed
1313
             match.
1314
 
1315
             FIXME - we still don't handle NAN([0xdigits]).  */
1316
          if (nancount - 1U < 2U) /* nancount && nancount < 3 */
1317
            {
1318
              /* Newlib's ungetc works even if we called __srefill in
1319
                 the middle of a partial parse, but POSIX does not
1320
                 guarantee that in all implementations of ungetc.  */
1321
              while (p > buf)
1322
                {
1323
                  _ungetwc_r (rptr, *--p, fp); /* [-+nNaA] */
1324
                  --nread;
1325
                }
1326
              goto match_failure;
1327
            }
1328
          /* Likewise for 'inf' and 'infinity'.  But be careful that
1329
             'infinite' consumes only 3 characters, leaving the stream
1330
             at the second 'i'.  */
1331
          if (infcount - 1U < 7U) /* infcount && infcount < 8 */
1332
            {
1333
              if (infcount >= 3) /* valid 'inf', but short of 'infinity' */
1334
                while (infcount-- > 3)
1335
                  {
1336
                    _ungetwc_r (rptr, *--p, fp); /* [iInNtT] */
1337
                    --nread;
1338
                  }
1339
              else
1340
                {
1341
                  while (p > buf)
1342
                    {
1343
                      _ungetwc_r (rptr, *--p, fp); /* [-+iInN] */
1344
                      --nread;
1345
                    }
1346
                  goto match_failure;
1347
                }
1348
            }
1349
          /*
1350
           * If no digits, might be missing exponent digits
1351
           * (just give back the exponent) or might be missing
1352
           * regular digits, but had sign and/or decimal point.
1353
           */
1354
          if (flags & NDIGITS)
1355
            {
1356
              if (flags & EXPOK)
1357
                {
1358
                  /* no digits at all */
1359
                  while (p > buf)
1360
                    {
1361
                      _ungetwc_r (rptr, *--p, fp); /* [-+.] */
1362
                      --nread;
1363
                    }
1364
                  goto match_failure;
1365
                }
1366
              /* just a bad exponent (e and maybe sign) */
1367
              c = *--p;
1368
              --nread;
1369
              if (c != L'e' && c != L'E')
1370
                {
1371
                  _ungetwc_r (rptr, c, fp); /* [-+] */
1372
                  c = *--p;
1373
                  --nread;
1374
                }
1375
              _ungetwc_r (rptr, c, fp); /* [eE] */
1376
            }
1377
          if ((flags & SUPPRESS) == 0)
1378
            {
1379
              double res = 0;
1380
#ifdef _NO_LONGDBL
1381
#define QUAD_RES res;
1382
#else  /* !_NO_LONG_DBL */
1383
              long double qres = 0;
1384
#define QUAD_RES qres;
1385
#endif /* !_NO_LONG_DBL */
1386
              long new_exp = 0;
1387
 
1388
              *p = 0;
1389
              if ((flags & (DPTOK | EXPOK)) == EXPOK)
1390
                {
1391
                  exp_adjust = zeroes - leading_zeroes;
1392
                  new_exp = -exp_adjust;
1393
                  exp_start = p;
1394
                }
1395
              else if (exp_adjust)
1396
                new_exp = _wcstol_r (rptr, (exp_start + 1), NULL, 10) - exp_adjust;
1397
              if (exp_adjust)
1398
                {
1399
 
1400
                  /* If there might not be enough space for the new exponent,
1401
                     truncate some trailing digits to make room.  */
1402
                  if (exp_start >= buf + sizeof (buf) - MAX_LONG_LEN)
1403
                    exp_start = buf + sizeof (buf) - MAX_LONG_LEN - 1;
1404
                 swprintf (exp_start, MAX_LONG_LEN, L"e%ld", new_exp);
1405
                }
1406
 
1407
              /* FIXME: We don't have wcstold yet. */
1408
#if 0//ndef _NO_LONGDBL /* !_NO_LONGDBL */
1409
              if (flags & LONGDBL)
1410
                qres = _wcstold_r (rptr, buf, NULL);
1411
              else
1412
#endif
1413
                res = _wcstod_r (rptr, buf, NULL);
1414
 
1415
              if (flags & LONG)
1416
                {
1417
                  dp = GET_ARG (N, ap, double *);
1418
                  *dp = res;
1419
                }
1420
              else if (flags & LONGDBL)
1421
                {
1422
                  ldp = GET_ARG (N, ap, _LONG_DOUBLE *);
1423
                  *ldp = QUAD_RES;
1424
                }
1425
              else
1426
                {
1427
                  flp = GET_ARG (N, ap, float *);
1428
                  if (isnan (res))
1429
                    *flp = nanf (NULL);
1430
                  else
1431
                    *flp = res;
1432
                }
1433
              nassigned++;
1434
            }
1435
          break;
1436
        }
1437
#endif /* FLOATING_POINT */
1438
        }
1439
    }
1440
input_failure:
1441
  /* On read failure, return EOF failure regardless of matches; errno
1442
     should have been set prior to here.  On EOF failure (including
1443
     invalid format string), return EOF if no matches yet, else number
1444
     of matches made prior to failure.  */
1445
  _funlockfile (fp);
1446
  __sfp_lock_release ();
1447
  return nassigned && !(fp->_flags & __SERR) ? nassigned : EOF;
1448
match_failure:
1449
all_done:
1450
  /* Return number of matches, which can be 0 on match failure.  */
1451
  _funlockfile (fp);
1452
  __sfp_lock_release ();
1453
  return nassigned;
1454
}
1455
 
1456
#ifndef _NO_POS_ARGS
1457
/* Process all intermediate arguments.  Fortunately, with wscanf, all
1458
   intermediate arguments are sizeof(void*), so we don't need to scan
1459
   ahead in the format string.  */
1460
static void *
1461
get_arg (int n, va_list *ap, int *numargs_p, void **args)
1462
{
1463
  int numargs = *numargs_p;
1464
  while (n >= numargs)
1465
    args[numargs++] = va_arg (*ap, void *);
1466
  *numargs_p = numargs;
1467
  return args[n];
1468
}
1469
#endif /* !_NO_POS_ARGS */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.