source: trunk/libs/newlib/src/newlib/libc/stdlib/strtoll.c @ 577

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

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

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