]> git.proxmox.com Git - mirror_edk2.git/blame - StdLib/LibC/StdLib/strtoumax.c
Add Socket Libraries.
[mirror_edk2.git] / StdLib / LibC / StdLib / strtoumax.c
CommitLineData
2aa62f2b 1/* $NetBSD: strtoumax.c,v 1.1 2006/04/22 15:33:33 thorpej Exp $ */\r
2\r
3/*\r
4 * Copyright (c) 1990, 1993\r
5 * The Regents of the University of California. All rights reserved.\r
6 *\r
7 * Redistribution and use in source and binary forms, with or without\r
8 * modification, are permitted provided that the following conditions\r
9 * are met:\r
10 * 1. Redistributions of source code must retain the above copyright\r
11 * notice, this list of conditions and the following disclaimer.\r
12 * 2. Redistributions in binary form must reproduce the above copyright\r
13 * notice, this list of conditions and the following disclaimer in the\r
14 * documentation and/or other materials provided with the distribution.\r
15 * 3. Neither the name of the University nor the names of its contributors\r
16 * may be used to endorse or promote products derived from this software\r
17 * without specific prior written permission.\r
18 *\r
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\r
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\r
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r
29 * SUCH DAMAGE.\r
30 */\r
31#include <LibConfig.h>\r
32#include <sys/EfiCdefs.h>\r
33\r
34#if !defined(_KERNEL) && !defined(_STANDALONE)\r
35#if defined(LIBC_SCCS) && !defined(lint)\r
36#if 0\r
37static char sccsid[] = "from: @(#)strtoul.c 8.1 (Berkeley) 6/4/93";\r
38#else\r
39__RCSID("$NetBSD: strtoumax.c,v 1.1 2006/04/22 15:33:33 thorpej Exp $");\r
40#endif\r
41#endif /* LIBC_SCCS and not lint */\r
42\r
43#include "namespace.h"\r
44\r
45#include <assert.h>\r
46#include <ctype.h>\r
47#include <errno.h>\r
48#include <inttypes.h>\r
49#include <stddef.h>\r
50\r
d7ce7006 51#include <Library/BaseLib.h>\r
52\r
2aa62f2b 53#ifdef __weak_alias\r
54__weak_alias(strtoumax, _strtoumax)\r
55#endif\r
56\r
57#else /* !_KERNEL && !_STANDALONE */\r
58#include <sys/param.h>\r
59#include <lib/libkern/libkern.h>\r
60#endif /* !_KERNEL && !_STANDALONE */\r
61\r
62/*\r
63 * Convert a string to an uintmax_t.\r
64 *\r
65 * Ignores `locale' stuff. Assumes that the upper and lower case\r
66 * alphabets and digits are each contiguous.\r
67 */\r
68uintmax_t\r
69strtoumax(const char *nptr, char **endptr, int base)\r
70{\r
71 const char *s;\r
72 uintmax_t acc, cutoff;\r
73 int c;\r
74 int neg, any, cutlim;\r
75\r
76 _DIAGASSERT(nptr != NULL);\r
77 /* endptr may be NULL */\r
78\r
79 /*\r
80 * See strtol for comments as to the logic used.\r
81 */\r
82 s = nptr;\r
83 do {\r
84 c = (unsigned char) *s++;\r
85 } while (isspace(c));\r
86 if (c == '-') {\r
87 neg = 1;\r
88 c = *s++;\r
89 } else {\r
90 neg = 0;\r
91 if (c == '+')\r
92 c = *s++;\r
93 }\r
94 if ((base == 0 || base == 16) &&\r
95 c == '0' && (*s == 'x' || *s == 'X')) {\r
96 c = s[1];\r
97 s += 2;\r
98 base = 16;\r
99 }\r
100 if (base == 0)\r
101 base = c == '0' ? 8 : 10;\r
102\r
d7ce7006 103 cutoff = DivU64x32 ((UINT64) UINTMAX_MAX, (UINT32) base);\r
104 cutlim = (int) ModU64x32 ((UINT64) UINTMAX_MAX, (UINT32) base);\r
2aa62f2b 105 for (acc = 0, any = 0;; c = (unsigned char) *s++) {\r
106 if (isdigit(c))\r
107 c -= '0';\r
108 else if (isalpha(c)) {\r
109#if defined(_KERNEL) || defined(_STANDALONE)\r
110 c = toupper(c) - 'A' + 10;\r
111#else\r
112 c -= isupper(c) ? 'A' - 10 : 'a' - 10;\r
113#endif\r
114 } else\r
115 break;\r
116 if (c >= base)\r
117 break;\r
118 if (any < 0)\r
119 continue;\r
120 if (acc > cutoff || (acc == cutoff && c > cutlim)) {\r
121#if defined(_KERNEL) || defined(_STANDALONE)\r
122 if (endptr)\r
123 *endptr = __UNCONST(nptr);\r
124 return UINTMAX_MAX;\r
125#else\r
126 any = -1;\r
127 acc = UINTMAX_MAX;\r
128 errno = ERANGE;\r
129#endif\r
130 } else {\r
131 any = 1;\r
132 acc *= (uintmax_t)base;\r
133 acc += c;\r
134 }\r
135 }\r
136 if (neg && any > 0)\r
137 acc = (uintmax_t)(-((intmax_t)acc));\r
138 if (endptr != 0)\r
139 *endptr = __UNCONST(any ? s - 1 : nptr);\r
140 return (acc);\r
141}\r