Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
num_get.cpp
Go to the documentation of this file.
1
29#define _RWSTD_LIB_SRC
30#include <rw/_defs.h>
31
32#include "setlocale.h"
33#include "strtol.h"
34#include "punct.h" // for __rw_get_stdio_fmat
35
36#include <ios> // for ios_base, needed by <rw/_punct.h>
37#include <loc/_num_get.h>
38
39#include <errno.h> // for ERANGE, errno
40#include <float.h> // for {DBL,FLT,LDBL}_{MIN,MAX}
41#include <stdio.h> // for printf()
42#include <stdlib.h> // for strtod()
43#include <string.h> // for memcpy()
44
45#include <rw/_defs.h>
46
47
48// in case EINVAL is not #defined in errno.h
49#ifdef EINVAL
50# define _RWSTD_EINVAL EINVAL
51#else // if !defined (EINVAL)
52// actual value of EINVAL on both Linux and SunOS is 22
53# define _RWSTD_EINVAL 22
54#endif // EINVAL
55
56
57
58#if defined (_RWSTD_NO_STRTOF) && !defined (_RWSTD_NO_STRTOF_IN_LIBC)
59
60# undef _RWSTD_NO_STRTOF
61
62extern "C" float strtof (const char*, char**);
63
64#endif // NO_STRTOF && !NO_STRTOF_IN_LIBC
65
66#if defined (_RWSTD_NO_STRTOLD) && !defined (_RWSTD_NO_STRTOLD_IN_LIBC)
67
68# undef _RWSTD_NO_STRTOLD
69
70extern "C" long double strtold (const char*, char**);
71
72#endif // NO_STRTOLD && !NO_STRTOLD_IN_LIBC
73
74
75#ifdef _RWSTD_MSVC
76 // shut up useless MSVC warning: unary minus operator
77 // applied to unsigned type, result still unsigned
78# pragma warning (disable: 4146)
79#endif // _RWSTD_MSVC
80
81
83
84
85typedef unsigned char UChar;
86
87
88#ifndef _RWSTD_NO_OBJECT_MANGLING
89
90extern "C" {
91
92#else // if defined (_RWSTD_NO_OBJECT_MANGLING)
93
94extern "C++" {
95
96#endif // _RWSTD_NO_OBJECT_MANGLING
97
98
99extern const float __rw_flt_infinity;
100extern const double __rw_dbl_infinity;
101
102#ifndef _RWSTD_NO_LONG_DOUBLE
103
104extern const long double __rw_ldbl_infinity;
105
106#endif // _RWSTD_NO_LONG_DOUBLE
107
108} // extern "C"/"C++"
109
110
111// verifies that the `grps' array of size `ngrps' representing the
112// lengths of individual groups of digits separated by thousands_sep
113// in the representation of a number corresponds to the `grping' array
114// of `ngrpings' elements
115// returns a non-negative number of success, negative number whose
116// absolute value indicates the bad group on failure
117
118// Examples of valid groups:
119//
120// sequence grps grping
121//
122// 123 "\3" "\3\2" 3 <= 3,
123// 1,234 "\1\3" "\3\2" 1 <= 2 && 3 == 3
124// 1,23,456 "\1\2\3" "\3\2" 1 <= 2 && 2 == 2 && 3 == 3
125// 12,34,567 "\2\2\3" "\3\2" 2 <= 2 && 2 == 2 && 3 == 3
126// 1,34,56,789 "\1\2\2\3" "\3\2" 1 <= 2 && 2 == 2 && 2 == 2 && 3 == 3
127
128// Examples of invalid groups:
129//
130// sequence grps grping
131//
132// 123 "\3" "\1\2" !(3 <= 1)
133// 1,2,34 "\1\1\2" "\1\3" 1 <= 1 && 1 == 1 && !(2 == 3)
134// 1,23,456 "\1\2\3" "\1\2" 1 <= 1 && 2 == 2 && !(3 == 2)
135
137__rw_check_grouping (const char *grps, _RWSTD_SIZE_T ngrps,
138 const char *grping, _RWSTD_SIZE_T ngrpings)
139{
140 if (!ngrps || !ngrpings)
141 return 0;
142
143 _RWSTD_ASSERT (0 != grps);
144 _RWSTD_ASSERT (0 != grping);
145
146 // current grouping number
147 _RWSTD_SIZE_T grpn = ngrpings;
148
149 // find the last non-zero grouping if it exists (see below)
150 while (grpn-- != ngrpings && !grping [grpn]);
151
152 // the index of the last meaningful grouping (e.g., `grphi' of
153 // "\3\0\0\0" is 2 since the redundant NULs can be safely ignored)
154 const _RWSTD_SIZE_T grphi = (_RWSTD_SIZE_T)(-1) == grpn ? 0 : grpn;
155
156 grpn = 0;
157
158 typedef const UChar* PCUChar;
159
160 // iterate over elements of `groups' starting with the least significant
161 // one (at the greatest index), comparing each against the relevant
162 // element of `groupings' (at the lowest index)
163 for (PCUChar g = _RWSTD_REINTERPRET_CAST (PCUChar, grps + ngrps - 1),
164 e = _RWSTD_REINTERPRET_CAST (PCUChar, grping); ; --g) {
165
166 typedef const void* PVoid;
167
168 if (PVoid (g) == PVoid (grps)) {
169 // the most significant group may be shorter (but not empty)
170 if (*g > *e || !*g) {
171 // subtracting from 0 to avoid warnings about
172 // applying the - operator to an unsigned type
173 grpn = 0U - (grpn + 1U);
174 }
175
176 break;
177 }
178
179 if (*g != *e) {
180 // all but the most significant group must be exactly
181 // as long as the last expected group length
182 grpn = 0U - (grpn + 1U);
183 break;
184 }
185
186 if (grpn++ < grphi)
187 ++e; // `*e' is the expected length of the group
188 }
189
190 // negative return value indicates an error
191 return int (grpn);
192}
193
194
195// array of 1-based indices for each 8-bit character into an internal
196// table of values of each roman digit, i.e., I, V, X, L, C, D, and M
197// elements with value greater than 7 do not correspond to a roman digit
198_RWSTD_EXPORT extern const UChar
199__rw_roman_inxs[] = {
200 // 0 1 2 3 4 5 6 7 8 9 a b c d e f
201 // NUL SOH STX ETX EOT ENQ ACK BEL BS TAB LF VT FF CR SO SI
202 /* 0 */ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
203 // DLE DC1 DC2 DC3 DC4 NAK SYN ETB CAN EM SUB ESC FS GS RS US
204 /* 1 */ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
205 // SPC ! " # $ % ' ' ( ) * + , - . /
206 /* 2 */ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
207 // 0 1 2 3 4 5 6 7 8 9 : ; < = > ?
208 /* 3 */ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
209 // @ A B C D E F G H I J K L M N O
210 /* 4 */ 9, 9, 9, 5, 6, 9, 9, 9, 9, 1, 9, 9, 4, 7, 9, 9,
211 // P Q R S T U V W X Y Z [ \ ] ^ _
212 /* 5 */ 9, 9, 9, 9, 9, 9, 2, 9, 3, 9, 9, 9, 9, 9, 9, 9,
213 // ` a b c d e f g h i j k l m n o
214 /* 6 */ 9, 9, 9, 5, 6, 9, 9, 9, 9, 1, 9, 9, 4, 7, 9, 9,
215 // p q r s t u v w x y z { | } ~ DEL
216 /* 7 */ 9, 9, 9, 9, 9, 9, 2, 9, 3, 9, 9, 9, 9, 9, 9, 9,
217 // extended ascii below
218 /* 8 */ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
219 /* 9 */ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
220 /* a */ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
221 /* b */ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
222 /* c */ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
223 /* d */ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
224 /* e */ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
225 /* f */ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9
226};
227
228
229static const int __rw_roman_digits[] = {
230 // 1 2 3 4 5 6 7 8 9
231 -1, 1, 5, 10, 50, 100, 500, 1000, -1, -1
232};
233
234
235// parse a string ot roman digits, produce a non-zero numeric value
236// on success, 0 otherwise, set `end' to point one past the last
237// successfully interpreted character
238static unsigned long __rw_get_roman (const char *str)
239{
240 _RWSTD_ASSERT (str && *str);
241
242#define ROMAN_DIGIT(c) __rw_roman_digits [__rw_roman_inxs [UChar (c)]]
243
244 unsigned long val = 0;
245
246 for (; str [1]; ++str) {
247 const int digit_1 = ROMAN_DIGIT (str [0]);
248 const int digit_2 = ROMAN_DIGIT (str [1]);
249
250 if (digit_1 < digit_2)
251 val -= digit_1;
252 else
253 val += digit_1;
254 }
255
256 val += ROMAN_DIGIT (*str);
257
258 return val;
259}
260
261
262// validates a floating point value and errno value
263template <class FloatT>
264inline FloatT
265__rw_validate (FloatT val, FloatT fmin, FloatT finf, char sign, int &err)
266{
267 if (ERANGE == err) {
268
269 if (val < -(fmin)) {
270 // negative overflow: store -infinity and set failbit
271 val = -finf;
272 err = _RWSTD_IOS_FAILBIT;
273 }
274 else if (val > (fmin)) {
275 // positive overflow: store +infinity and set failbit
276 val = finf;
277 err = _RWSTD_IOS_FAILBIT;
278 }
279 else { // val >= fmin && val <= max
280 // benign underflow: store +/-fmin, clear failbit
281 val = '-' == sign ? -(fmin) : (fmin);
282 err = 0;
283 }
284 }
285 else
286 err = 0;
287
288 return val;
289}
290
291
293__rw_get_num (void *pval, const char *buf, int type, int flags,
294 const char *groups, _RWSTD_SIZE_T ngroups,
295 const char *grouping, _RWSTD_SIZE_T ngroupings)
296{
297 // 22.2.2.1.2, p3: Stage 1
298 int err = 0; // errno value, ERANGE, or 0
299
300 _RWSTD_ASSERT (0 != buf);
301 _RWSTD_ASSERT ('+' == *buf || '-' == *buf);
302
303 if (!(type & __rw_facet::_C_floating)) {
304
306 // integral parsing (including void*)
307
308 int base = unsigned (flags) >> _RWSTD_IOS_BASEOFF;
309
310 if (!base)
311 base = 10;
312
313 union {
314#ifdef _RWSTD_LONG_LONG
315
317 unsigned _RWSTD_LONG_LONG ull;
318
319#endif // _RWSTD_LONG_LONG
320
321 long l;
322 unsigned long ul;
323 } val;
324
325 if (1 == base) {
326 // treat numeric (i.e., non-Roman) input in base-1 as decimal
327 const UChar digit = __rw_digit_map [UChar (buf [1])];
328
329 if (digit < 10) {
330 val.ul = _RW::__rw_strtoul (buf, &err, 10);
331 }
332 else {
333 _RWSTD_ASSERT ('+' == *buf);
334
335 val.ul = __rw_get_roman (buf + 1);
336 }
337
338 val.l = _RWSTD_STATIC_CAST (long, val.ul);
339 }
340 else if (__rw_facet::_C_ullong == type) {
341
342#ifdef _RWSTD_LONG_LONG
343
344 val.ull = _RW::__rw_strtoull (buf, &err, base);
345
346#else // if !defined (_RWSTD_LONG_LONG)
347
348 _RWSTD_ASSERT (!"logic error: unsigned long long not configured");
349
350#endif // _RWSTD_LONG_LONG
351 }
352 else if (__rw_facet::_C_llong == type) {
353
354#ifdef _RWSTD_LONG_LONG
355
356 val.ll = _RW::__rw_strtoll (buf, &err, base);
357
358#else // if !defined (_RWSTD_LONG_LONG)
359
360 _RWSTD_ASSERT (!"logic error: long long not configured");
361
362#endif // _RWSTD_LONG_LONG
363 }
364 else if (type & __rw_facet::_C_signed || __rw_facet::_C_bool == type) {
365 val.l = _RW::__rw_strtol (buf, &err, base);
366 }
367 else if (__rw_facet::_C_pvoid == type) {
368
369#if defined (_RWSTD_LONG_LONG) && _RWSTD_PTR_SIZE > _RWSTD_LONG_SIZE
370 // assume pointers fit into long long
371 val.ull = _RW::__rw_strtoull (buf, &err, base);
372#else
373 val.ul = _RW::__rw_strtoul (buf, &err, base);
374#endif
375 }
376 else {
377 val.ul = _RW::__rw_strtoul (buf, &err, base);
378 }
379
380 if (_RWSTD_EINVAL == err)
381 return _RWSTD_IOS_FAILBIT;
382
383 _RWSTD_ASSERT (0 != pval);
384
385 switch (type) {
386 case __rw_facet::_C_bool:
387 if (0 == val.l || 1 == val.l) {
388 *_RWSTD_STATIC_CAST (bool*, pval) = 1 == val.l;
389 }
390 else
391 err = ERANGE;
392
393 break;
394
395 case __rw_facet::_C_ushort:
396 // detect and handle unsigned overflow
397 if (val.ul > _RWSTD_USHRT_MAX) {
398 val.ul = _RWSTD_USHRT_MAX;
399 err = ERANGE;
400 }
401 else {
402 if ('-' == *buf)
403 val.ul = _RWSTD_USHRT_MAX - val.ul + 1;
404 }
405
406 *_RWSTD_STATIC_CAST (unsigned short*, pval) =
407 _RWSTD_STATIC_CAST (unsigned short, val.ul);
408 break;
409
410 case __rw_facet::_C_short:
411 // detect and handle overflow
412 if (val.l < _RWSTD_SHRT_MIN) {
413 val.l = long (_RWSTD_SHRT_MIN);
414 err = ERANGE;
415 }
416 else if (val.l > _RWSTD_SHRT_MAX) {
417 val.l = long (_RWSTD_SHRT_MAX);
418 err = ERANGE;
419 }
420
421 *_RWSTD_STATIC_CAST (short*, pval) =
422 _RWSTD_STATIC_CAST (short, val.l);
423 break;
424
425 case __rw_facet::_C_uint:
426
427 // detect and handle unsigned overflow
428
429#if _RWSTD_UINT_MAX < _RWSTD_ULONG_MAX
430
431 if (val.ul > _RWSTD_UINT_MAX)
432
433#else // if _RWSTD_UINT_MAX >= _RWSTD_ULONG_MAX
434
435 if (val.ul == _RWSTD_ULONG_MAX && ERANGE == err)
436
437#endif // _RWSTD_UINT_MAX < _RWSTD_ULONG_MAX
438
439 {
440 val.ul = _RWSTD_UINT_MAX;
441 }
442 else {
443 if ('-' == *buf)
444 val.ul = _RWSTD_UINT_MAX - val.ul + 1;
445 }
446
447 *_RWSTD_STATIC_CAST (unsigned*, pval) = unsigned (val.ul);
448 break;
449
450 case __rw_facet::_C_int:
451
452 // detect and handle overflow
453
454#if _RWSTD_UINT_MAX < _RWSTD_ULONG_MAX
455
456 if (val.l < _RWSTD_INT_MIN) {
457 val.l = long (_RWSTD_INT_MIN);
458 err = ERANGE;
459 }
460 else if (val.l > _RWSTD_INT_MAX) {
461 val.l = long (_RWSTD_INT_MAX);
462 err = ERANGE;
463 }
464
465#else // if _RWSTD_UINT_MAX >= _RWSTD_ULONG_MAX
466
467 if (ERANGE == err) {
468 if (_RWSTD_LONG_MIN == val.l)
469 val.l = long (_RWSTD_INT_MIN);
470 else if (_RWSTD_LONG_MAX == val.l)
471 val.l = long (_RWSTD_INT_MAX);
472 }
473
474#endif // _RWSTD_UINT_MAX < _RWSTD_ULONG_MAX
475
476 *_RWSTD_STATIC_CAST (int*, pval) = int (val.l);
477 break;
478
479 case __rw_facet::_C_ulong:
480 *_RWSTD_STATIC_CAST (unsigned long*, pval) = val.ul;
481 break;
482
483 case __rw_facet::_C_long:
484 *_RWSTD_STATIC_CAST (long*, pval) = val.l;
485 break;
486
487#ifdef _RWSTD_LONG_LONG
488
489 case __rw_facet::_C_ullong:
490 *_RWSTD_STATIC_CAST (unsigned _RWSTD_LONG_LONG*, pval) = val.ull;
491 break;
492
493 case __rw_facet::_C_llong:
495 break;
496
497#endif // _RWSTD_LONG_LONG
498
499 case __rw_facet::_C_pvoid:
500 *_RWSTD_STATIC_CAST (void**, pval) =
501#if defined (_RWSTD_LONG_LONG) && _RWSTD_PTR_SIZE > _RWSTD_LONG_SIZE
502 _RWSTD_REINTERPRET_CAST (void*, val.ull);
503#else
504 _RWSTD_REINTERPRET_CAST (void*, val.ul);
505#endif
506
507 // disable grouping
508 grouping = "";
509 break;
510
511 }
512
513 if (err)
514 err = _RWSTD_IOS_FAILBIT;
515 }
516 else {
518 // floating point parsing
519
520 // fail if the sequence is empty
521 if (!*buf)
522 return _RWSTD_IOS_FAILBIT;
523
524 char *end;
525
526 // save errno value, reset only if ERANGE to distinguish strtol()
527 // failure from success if errno already set on function entry
528 const int errno_save = errno;
529
530 if (ERANGE == errno_save)
531 errno = 0;
532
533 _RWSTD_ASSERT (0 != pval);
534
535 switch (type) {
536 case __rw_facet::_C_float: {
537
538#ifndef _RWSTD_NO_STRTOF
539
540 // assumes `buf' is formatted for the current locale
541 // specifically, affects the value of decimal_point
542 float f = strtof (_RWSTD_CONST_CAST (char*, buf), &end);
543
544 err = errno;
545
546 _RWSTD_ASSERT (0 != end);
547
548 if ('.' == *end || end == buf && '.' == buf [1]) {
549 // on failure caused by an unrecognized decimal point
550 // set teporarily the global locale to "C" and reparse
551 __rw_setlocale loc ("C", _RWSTD_LC_NUMERIC);
552
553 f = strtof (_RWSTD_CONST_CAST (char*, buf), &end);
554 err = errno;
555 }
556
557 // restore errno if it was reset above
558 if (ERANGE == errno_save)
559 errno = ERANGE;
560
561 if (*end)
562 return _RWSTD_IOS_FAILBIT;
563
564 *_RWSTD_STATIC_CAST (float*, pval) =
565 __rw_validate (f, float (_RWSTD_FLT_MIN),
566 __rw_flt_infinity, *buf, err);
567
568 break;
569
570#else // if defined (_RWSTD_NO_STRTOF)
571
572 // assumes `buf' is formatted for the current locale
573 // specifically, affects the value of decimal_point
574 double d = strtod (buf, &end);
575 err = errno;
576
577 // restore errno if it was reset above
578 if (ERANGE == errno_save)
579 errno = ERANGE;
580
581 _RWSTD_ASSERT (0 != end);
582
583 if ('.' == *end || end == buf && '.' == buf [1]) {
584 // on failure caused by an unrecognized decimal point
585 // set teporarily the global locale to "C" and reparse
586 __rw_setlocale loc ("C", _RWSTD_LC_NUMERIC);
587
588 d = strtod (buf, &end);
589 }
590
591 if (*end)
592 return _RWSTD_IOS_FAILBIT;
593
594 // handle (benign) overflow and underflow
595
596 if (d < -double (_RWSTD_FLT_MAX)) {
597 // negative overflow (magnitude is too large to represent)
598 // store negative infinity and set failbit
599 d = -__rw_flt_infinity;
600 err = _RWSTD_IOS_FAILBIT;
601 }
602 else if (d > double (_RWSTD_FLT_MAX)) {
603 // positive overflow (magnitude is too large to represent)
604 // store positive infinity and set failbit
605 d = __rw_flt_infinity;
606 err = _RWSTD_IOS_FAILBIT;
607 }
608 else if (d > 0.0 && d < double (_RWSTD_FLT_MIN)) {
609 // positive underflow (magnitude is too small to represent)
610 // store FLT_MIN and clear failbit
611 d = _RWSTD_FLT_MIN;
612 err = 0;
613 }
614 else if (d < 0.0 && d > -double (_RWSTD_FLT_MIN)) {
615 // negative underflow (magnitude is too small to represent)
616 // store -FLT_MIN and clear failbit
617 d = -_RWSTD_FLT_MIN;
618 err = 0;
619 }
620 else
621 err = 0;
622
623 *_RWSTD_STATIC_CAST (float*, pval) =
624 _RWSTD_STATIC_CAST (float, d);
625 break;
626
627#endif // _RWSTD_NO_STRTOF
628
629 }
630
631#ifdef _RWSTD_NO_STRTOLD
632# if DBL_DIG == LDBL_DIG && DBL_MAX_EXP == LDBL_MAX_EXP
633
634 // strtold() is not defined and the size and domain of long double
635 // is the same as that of double; use strtod() instead of sscanf()
636 // for better precision
637# define LDBL_SAME_AS_DBL
638
639 case __rw_facet::_C_ldouble:
640
641# endif // DBL_DIG == LDBL_DIG && DBL_MAX_EXP == LDBL_MAX_EXP
642#endif // _RWSTD_NO_STRTOLD
643
644 case __rw_facet::_C_double: {
645 // assumes `buf' is formatted for the current locale
646 // specifically, affects the value of decimal_point
647 double d = strtod (buf, &end);
648 err = errno;
649
650 _RWSTD_ASSERT (0 != end);
651
652 if ('.' == *end || end == buf && '.' == buf [1]) {
653 // on failure caused by an unrecognized decimal point
654 // set teporarily the global locale to "C" and reparse
655 __rw_setlocale loc ("C", _RWSTD_LC_NUMERIC);
656
657 d = strtod (buf, &end);
658 err = errno;
659 }
660
661 // restore errno if it was reset above
662 if (ERANGE == errno_save)
663 errno = errno_save;
664
665 if (*end)
666 return _RWSTD_IOS_FAILBIT;
667
668 *_RWSTD_STATIC_CAST (double*, pval) =
669 __rw_validate (d, double (_RWSTD_DBL_MIN),
670 __rw_dbl_infinity, *buf, err);
671 break;
672 }
673
674
675#ifndef LDBL_SAME_AS_DBL
676
677 case __rw_facet::_C_ldouble: {
678
679 typedef long double LDbl;
680
681# ifndef _RWSTD_NO_LONG_DOUBLE
682
683 LDbl ld;
684
685# ifndef _RWSTD_NO_STRTOLD
686
687 // assumes `buf' is formatted for the current locale
688 // specifically, affects the value of decimal_point
689# if !defined (_RWSTD_OS_HP_UX) || !defined (_LONG_DOUBLE)
690
691 // not HP-UX or HP-UX with gcc
692 ld = strtold (buf, &end);
693
694# else // UP-UX with _LONG_DOUBLE
695
696 // HP-UX strtold() returns struct long_double
697 // the macro _LONG_DOUBLE is #defined when the struct is defined
698 // note that gcc's replacement <stdlib.h> may actually define the
699 // function with the correct signature
700
701 union {
702 LDbl ld;
703 long_double words;
704 } u;
705
706 u.words = strtold (buf, &end);
707 ld = u.ld;
708
709# ifndef __ia64
710
711 // inefficiently working around HP-UX/PA-RISC strtold("0")
712 // bug #615: strtold("0", &end) fails to set the end pointer
713 if ( end == buf
714 && 0 == errno
715 && ( '0' == *buf || '.' == *buf
716 || /* '+' or '-' */ 43 == __rw_digit_map [UChar (*buf)])) {
717
718 char *tmpend;
719 if ( 0.0 == strtod (buf, &tmpend)
720 && '\0' == *tmpend && 0 == errno)
721 end = tmpend;
722 }
723
724# endif // __ia64
725# endif // HP-UX, _LONG_DOUBLE
726
727 err = errno;
728
729 _RWSTD_ASSERT (0 != end);
730
731 if ('.' == *end || end == buf && '.' == buf [1]) {
732 // on failure caused by an unrecognized decimal point
733 // set teporarily the global locale to "C" and reparse
734 __rw_setlocale loc ("C", _RWSTD_LC_NUMERIC);
735
736# if !defined (_RWSTD_OS_HP_UX) || !defined (_LONG_DOUBLE)
737 ld = strtold (buf, &end);
738# else // HP-UX with _LONG_DOUBLE #defined
739 u.words = strtold (buf, &end);
740 ld = u.ld;
741# endif // HP-UX, _LONG_DOUBLE
742
743 err = errno;
744 }
745
746 // restore errno if it was reset above
747 if (ERANGE == errno_save)
748 errno = errno_save;
749
750 if (*end)
751 return _RWSTD_IOS_FAILBIT;
752
753# else // if defined (!_RWSTD_NO_STRTOLD)
754
755 flags &=
757
758 char fmatbuf [32];
759
760 const char* const fmt =
761 __rw_get_stdio_fmat (fmatbuf, type, flags, -1 /* ignore */);
762
763 // assumes `buf' is formatted for the current locale
764 // specifically, affects the value of decimal_point
765 const int n = sscanf (buf, fmt, pval);
766
767 // restore errno if it was reset above
768 if (ERANGE == errno_save)
769 errno = errno_save;
770
771 if (1 != n)
772 return _RWSTD_IOS_FAILBIT;
773
774 ld = *_RWSTD_STATIC_CAST (LDbl*, pval);
775
776# endif // _RWSTD_NO_STRTOLD
777
778 *_RWSTD_STATIC_CAST (LDbl*, pval) =
779 __rw_validate (ld, LDbl (_RWSTD_LDBL_MIN),
780 __rw_ldbl_infinity, *buf, err);
781
782# endif // _RWSTD_LONG_DOUBLE
783
784 break;
785 }
786
787#endif // LDBL_SAME_AS_DBL
788 }
789 }
790
791 _RWSTD_ASSERT (grouping);
792
793 // 22.2.2.1.2, p12: check digit grouping, if any
794 // note that grouping is optional and parsing fails due to bad format
795 // only if the positions thousands_sep's do not match those specified
796 // by grouping; in such cases, the value is still stored
797 if ( *grouping && ngroups > 1
798 && 0 > __rw_check_grouping (groups, ngroups, grouping, ngroupings)
799 || !*grouping && ngroups > 1)
800 err |= _RWSTD_IOS_FAILBIT;
801
802 return err;
803}
804
805
806} // namespace __rw
#define g
Definition 17.names.cpp:120
#define u
Definition 17.names.cpp:137
#define d
Definition 17.names.cpp:115
#define e
Definition 17.names.cpp:118
#define loc
Definition 17.names.cpp:492
#define f
Definition 17.names.cpp:119
#define buf
Definition 17.names.cpp:452
#define n
Definition 17.names.cpp:130
#define val
Definition 17.names.cpp:570
#define U
Definition 17.names.cpp:164
#define flags
@ LDbl
@ PVoid
const int end
#define ERANGE
#define _RWSTD_LONG_LONG
#define _RWSTD_EXPORT
Definition _defs.h:485
#define _RWSTD_REINTERPRET_CAST(T, x)
Definition _defs.h:535
#define _RWSTD_STATIC_CAST(T, x)
Definition _defs.h:534
#define _RWSTD_NAMESPACE(name)
Definition _defs.h:567
#define _RWSTD_IOS_FAILBIT
Definition _defs.h:810
#define _RWSTD_IOS_SHOWBASE
Definition _defs.h:775
#define _RWSTD_ASSERT(ignore)
Definition _defs.h:1108
#define _RWSTD_IOS_BASEOFF
Definition _defs.h:805
#define _RWSTD_CONST_CAST(T, x)
Definition _defs.h:536
#define _RWSTD_IOS_SHOWPOS
Definition _defs.h:777
#define _RWSTD_IOS_SHOWPOINT
Definition _defs.h:776
const char * str
Definition exec.cpp:170
unsigned long ul
unsigned char UChar
Definition collate.cpp:122
#define _RWSTD_EINVAL
Definition num_get.cpp:53
#define ROMAN_DIGIT(c)