source: trunk/libs/newlib/src/newlib/libc/stdlib/wcstoull.c @ 543

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

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

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