~mingw-w64/mingw-w64/experimental

« back to all changes in this revision

Viewing changes to ros-privexp/mingw-w64-crt/misc/strtoimax.c

  • Committer: NightStrike
  • Date: 2010-08-11 22:20:57 UTC
  • Revision ID: svn-v4:4407c894-4637-0410-b4f5-ada5f102cad1:experimental:3266
Branch for adding option for supporting ros

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**
 
2
 * This file has no copyright assigned and is placed in the Public Domain.
 
3
 * This file is part of the w64 mingw-runtime package.
 
4
 * No warranty is given; refer to the file DISCLAIMER.PD within this package.
 
5
 */
 
6
/*
 
7
    This source code was extracted from the Q8 package created and
 
8
    placed in the PUBLIC DOMAIN by Doug Gwyn <gwyn@arl.mil>
 
9
    last edit:  1999/11/05      gwyn@arl.mil
 
10
 
 
11
        Implements subclause 7.8.2 of ISO/IEC 9899:1999 (E).
 
12
 
 
13
        This particular implementation requires the matching <inttypes.h>.
 
14
        It also assumes that character codes for A..Z and a..z are in
 
15
        contiguous ascending order; this is true for ASCII but not EBCDIC.
 
16
*/
 
17
#include <stdlib.h>
 
18
#include <errno.h>
 
19
#include <ctype.h>
 
20
#include <inttypes.h>
 
21
 
 
22
/* Helper macros */
 
23
 
 
24
/* convert digit character to number, in any base */
 
25
#define ToNumber(c)     (isdigit(c) ? (c) - '0' : \
 
26
                         isupper(c) ? (c) - 'A' + 10 : \
 
27
                         islower(c) ? (c) - 'a' + 10 : \
 
28
                         -1             /* "invalid" flag */ \
 
29
                        )
 
30
/* validate converted digit character for specific base */
 
31
#define valid(n, b)     ((n) >= 0 && (n) < (b))
 
32
 
 
33
intmax_t
 
34
strtoimax(nptr, endptr, base)
 
35
        register const char * __restrict__      nptr;
 
36
        char ** __restrict__                    endptr;
 
37
        register int                            base;
 
38
        {
 
39
        register uintmax_t      accum;  /* accumulates converted value */
 
40
        register int            n;      /* numeral from digit character */
 
41
        int                     minus;  /* set iff minus sign seen */
 
42
        int                     toobig; /* set iff value overflows */
 
43
 
 
44
        if ( endptr != NULL )
 
45
                *endptr = (char *)nptr; /* in case no conversion's performed */
 
46
 
 
47
        if ( base < 0 || base == 1 || base > 36 )
 
48
                {
 
49
                errno = EDOM;
 
50
                return 0;               /* unspecified behavior */
 
51
                }
 
52
 
 
53
        /* skip initial, possibly empty sequence of white-space characters */
 
54
 
 
55
        while ( isspace(*nptr) )
 
56
                ++nptr;
 
57
 
 
58
        /* process subject sequence: */
 
59
 
 
60
        /* optional sign */
 
61
        if ( (minus = *nptr == '-') || *nptr == '+' )
 
62
                ++nptr;
 
63
 
 
64
        if ( base == 0 ) {
 
65
                if ( *nptr == '0' ) {
 
66
                        if ( nptr[1] == 'X' || nptr[1] == 'x' )
 
67
                                base = 16;
 
68
                        else
 
69
                                base = 8;
 
70
                }
 
71
                else
 
72
                                base = 10;
 
73
        }
 
74
        /* optional "0x" or "0X" for base 16 */
 
75
 
 
76
        if ( base == 16 && *nptr == '0' && (nptr[1] == 'X' || nptr[1] == 'x') )
 
77
                nptr += 2;              /* skip past this prefix */
 
78
 
 
79
        /* check whether there is at least one valid digit */
 
80
 
 
81
        n = ToNumber(*nptr);
 
82
        ++nptr;
 
83
 
 
84
        if ( !valid(n, base) )
 
85
                return 0;               /* subject seq. not of expected form */
 
86
 
 
87
        accum = n;
 
88
 
 
89
        for ( toobig = 0; n = ToNumber(*nptr), valid(n, base); ++nptr )
 
90
                if ( accum > (uintmax_t)(INTMAX_MAX / base + 2) ) /* major wrap-around */
 
91
                        toobig = 1;     /* but keep scanning */
 
92
                else
 
93
                        accum = base * accum + n;
 
94
 
 
95
        if ( endptr != NULL )
 
96
                *endptr = (char *)nptr; /* points to first not-valid-digit */
 
97
 
 
98
        if ( minus )
 
99
                {
 
100
                if ( accum > (uintmax_t)INTMAX_MAX + 1 )
 
101
                        toobig = 1;
 
102
                }
 
103
        else
 
104
        if ( accum > (uintmax_t)INTMAX_MAX )
 
105
                toobig = 1;
 
106
 
 
107
        if ( toobig )
 
108
                {
 
109
                errno = ERANGE;
 
110
                return minus ? INTMAX_MIN : INTMAX_MAX;
 
111
                }
 
112
        else
 
113
                return (intmax_t)(minus ? -accum : accum);
 
114
        }
 
115
 
 
116
long long __attribute__ ((alias ("strtoimax")))
 
117
strtoll (const char* __restrict__ nptr, char ** __restrict__ endptr, int base);