source: trunk/libs/newlib/src/newlib/libc/stdlib/strtoull.c @ 444

Last change on this file since 444 was 444, checked in by satin@…, 6 years ago

add newlib,libalmos-mkh, restructure shared_syscalls.h and mini-libc

File size: 7.3 KB
Line 
1/*
2FUNCTION
3        <<strtoull>>, <<strtoull_l>>---string to unsigned long long
4
5INDEX
6        strtoull
7
8INDEX
9        strtoull_l
10
11SYNOPSIS
12        #include <stdlib.h>
13        unsigned long long strtoull(const char *restrict <[s]>,
14                                    char **restrict <[ptr]>, int <[base]>);
15
16        #include <stdlib.h>
17        unsigned long long strtoull_l(const char *restrict <[s]>,
18                                      char **restrict <[ptr]>, int <[base]>,
19                                      locale_t <[locale]>);
20
21        unsigned long long _strtoull_r(void *<[reent]>,
22                                       const char *restrict <[s]>,
23                                       char **restrict <[ptr]>, int <[base]>);
24
25DESCRIPTION
26The function <<strtoull>> converts the string <<*<[s]>>> to
27an <<unsigned long long>>. First, it breaks down the string into three parts:
28leading whitespace, which is ignored; a subject string consisting
29of the digits meaningful in the radix specified by <[base]>
30(for example, <<0>> through <<7>> if the value of <[base]> is 8);
31and a trailing portion consisting of one or more unparseable characters,
32which always includes the terminating null character. Then, it attempts
33to convert the subject string into an unsigned long long integer, and returns the
34result.
35
36If the value of <[base]> is zero, the subject string is expected to look
37like a normal C integer constant (save that no optional sign is permitted):
38a possible <<0x>> indicating hexadecimal radix, and a number.
39If <[base]> is between 2 and 36, the expected form of the subject is a
40sequence of digits (which may include letters, depending on the
41base) representing an integer in the radix specified by <[base]>.
42The letters <<a>>--<<z>> (or <<A>>--<<Z>>) are used as digits valued from
4310 to 35. If <[base]> is 16, a leading <<0x>> is permitted.
44
45The subject sequence is the longest initial sequence of the input
46string that has the expected form, starting with the first
47non-whitespace character.  If the string is empty or consists entirely
48of whitespace, or if the first non-whitespace character is not a
49permissible digit, the subject string is empty.
50
51If the subject string is acceptable, and the value of <[base]> is zero,
52<<strtoull>> attempts to determine the radix from the input string. A
53string with a leading <<0x>> is treated as a hexadecimal value; a string with
54a leading <<0>> and no <<x>> is treated as octal; all other strings are
55treated as decimal. If <[base]> is between 2 and 36, it is used as the
56conversion radix, as described above. Finally, a pointer to the first
57character past the converted subject string is stored in <[ptr]>, if
58<[ptr]> is not <<NULL>>.
59
60If the subject string is empty (that is, if <<*>><[s]> does not start
61with a substring in acceptable form), no conversion
62is performed and the value of <[s]> is stored in <[ptr]> (if <[ptr]> is
63not <<NULL>>).
64
65<<strtoull_l>> is like <<strtoull>> but performs the conversion based on the
66locale specified by the locale object locale.  If <[locale]> is
67LC_GLOBAL_LOCALE or not a valid locale object, the behaviour is undefined.
68
69The alternate function <<_strtoull_r>> is a reentrant version.  The
70extra argument <[reent]> is a pointer to a reentrancy structure.
71
72RETURNS
73<<strtoull>>, <<strtoull_l>> return the converted value, if any. If no
74conversion was made, <<0>> is returned.
75
76<<strtoull>>, <<strtoull_l>> return <<ULONG_LONG_MAX>> if the magnitude
77of the converted value is too large, and sets <<errno>> to <<ERANGE>>.
78
79PORTABILITY
80<<strtoull>> is ANSI.
81<<strtoull_l>> is a GNU extension.
82
83<<strtoull>> requires no supporting OS subroutines.
84*/
85
86/*
87 * Copyright (c) 1990 Regents of the University of California.
88 * All rights reserved.
89 *
90 * Redistribution and use in source and binary forms, with or without
91 * modification, are permitted provided that the following conditions
92 * are met:
93 * 1. Redistributions of source code must retain the above copyright
94 *    notice, this list of conditions and the following disclaimer.
95 * 2. Redistributions in binary form must reproduce the above copyright
96 *    notice, this list of conditions and the following disclaimer in the
97 *    documentation and/or other materials provided with the distribution.
98 * 3. All advertising materials mentioning features or use of this software
99 *    must display the following acknowledgement:
100 *      This product includes software developed by the University of
101 *      California, Berkeley and its contributors.
102 * 4. Neither the name of the University nor the names of its contributors
103 *    may be used to endorse or promote products derived from this software
104 *    without specific prior written permission.
105 *
106 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
107 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
108 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
109 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
110 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
111 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
112 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
113 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
114 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
115 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
116 * SUCH DAMAGE.
117 */
118
119#define _GNU_SOURCE
120#include <_ansi.h>
121#include <limits.h>
122#include <ctype.h>
123#include <errno.h>
124#include <stdlib.h>
125#include <reent.h>
126#include "../locale/setlocale.h"
127
128/*
129 * Convert a string to an unsigned long long integer.
130 */
131static unsigned long long
132_strtoull_l (struct _reent *rptr, const char *__restrict nptr,
133             char **__restrict endptr, int base, locale_t loc)
134{
135        register const unsigned char *s = (const unsigned char *)nptr;
136        register unsigned long long acc;
137        register int c;
138        register unsigned long long cutoff;
139        register int neg = 0, any, cutlim;
140
141        /*
142         * See strtol for comments as to the logic used.
143         */
144        do {
145                c = *s++;
146        } while (isspace_l(c, loc));
147        if (c == '-') {
148                neg = 1;
149                c = *s++;
150        } else if (c == '+')
151                c = *s++;
152        if ((base == 0 || base == 16) &&
153            c == '0' && (*s == 'x' || *s == 'X')) {
154                c = s[1];
155                s += 2;
156                base = 16;
157        }
158        if (base == 0)
159                base = c == '0' ? 8 : 10;
160        cutoff = (unsigned long long)ULONG_LONG_MAX / (unsigned long long)base;
161        cutlim = (unsigned long long)ULONG_LONG_MAX % (unsigned long long)base;
162        for (acc = 0, any = 0;; c = *s++) {
163                if (c >= '0' && c <= '9')
164                        c -= '0';
165                else if (c >= 'A' && c <= 'Z')
166                        c -= 'A' - 10;
167                else if (c >= 'a' && c <= 'z')
168                        c -= 'a' - 10;
169                else
170                        break;
171                if (c >= base)
172                        break;
173               if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
174                        any = -1;
175                else {
176                        any = 1;
177                        acc *= base;
178                        acc += c;
179                }
180        }
181        if (any < 0) {
182                acc = ULONG_LONG_MAX;
183                rptr->_errno = ERANGE;
184        } else if (neg)
185                acc = -acc;
186        if (endptr != 0)
187                *endptr = (char *) (any ? (char *)s - 1 : nptr);
188        return (acc);
189}
190
191unsigned long long
192_strtoull_r (struct _reent *rptr,
193        const char *__restrict nptr,
194        char **__restrict endptr,
195        int base)
196{
197        return _strtoull_l (rptr, nptr, endptr, base, __get_current_locale ());
198}
199
200#ifndef _REENT_ONLY
201
202unsigned long long
203strtoull_l (const char *__restrict s, char **__restrict ptr, int base,
204            locale_t loc)
205{
206        return _strtoull_l (_REENT, s, ptr, base, loc);
207}
208
209unsigned long long
210strtoull (const char *__restrict s,
211        char **__restrict ptr,
212        int base)
213{
214        return _strtoull_l (_REENT, s, ptr, base, __get_current_locale ());
215}
216
217#endif
Note: See TracBrowser for help on using the repository browser.