]> git.proxmox.com Git - mirror_edk2.git/blame - StdLib/LibC/StdLib/strtoumax.c
Changes so that Argv points to narrow-character versions of the command-line arguments.
[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
51#ifdef __weak_alias\r
52__weak_alias(strtoumax, _strtoumax)\r
53#endif\r
54\r
55#else /* !_KERNEL && !_STANDALONE */\r
56#include <sys/param.h>\r
57#include <lib/libkern/libkern.h>\r
58#endif /* !_KERNEL && !_STANDALONE */\r
59\r
60/*\r
61 * Convert a string to an uintmax_t.\r
62 *\r
63 * Ignores `locale' stuff. Assumes that the upper and lower case\r
64 * alphabets and digits are each contiguous.\r
65 */\r
66uintmax_t\r
67strtoumax(const char *nptr, char **endptr, int base)\r
68{\r
69 const char *s;\r
70 uintmax_t acc, cutoff;\r
71 int c;\r
72 int neg, any, cutlim;\r
73\r
74 _DIAGASSERT(nptr != NULL);\r
75 /* endptr may be NULL */\r
76\r
77 /*\r
78 * See strtol for comments as to the logic used.\r
79 */\r
80 s = nptr;\r
81 do {\r
82 c = (unsigned char) *s++;\r
83 } while (isspace(c));\r
84 if (c == '-') {\r
85 neg = 1;\r
86 c = *s++;\r
87 } else {\r
88 neg = 0;\r
89 if (c == '+')\r
90 c = *s++;\r
91 }\r
92 if ((base == 0 || base == 16) &&\r
93 c == '0' && (*s == 'x' || *s == 'X')) {\r
94 c = s[1];\r
95 s += 2;\r
96 base = 16;\r
97 }\r
98 if (base == 0)\r
99 base = c == '0' ? 8 : 10;\r
100\r
101 cutoff = UINTMAX_MAX / (uintmax_t)base;\r
102 cutlim = (int)(UINTMAX_MAX % (uintmax_t)base);\r
103 for (acc = 0, any = 0;; c = (unsigned char) *s++) {\r
104 if (isdigit(c))\r
105 c -= '0';\r
106 else if (isalpha(c)) {\r
107#if defined(_KERNEL) || defined(_STANDALONE)\r
108 c = toupper(c) - 'A' + 10;\r
109#else\r
110 c -= isupper(c) ? 'A' - 10 : 'a' - 10;\r
111#endif\r
112 } else\r
113 break;\r
114 if (c >= base)\r
115 break;\r
116 if (any < 0)\r
117 continue;\r
118 if (acc > cutoff || (acc == cutoff && c > cutlim)) {\r
119#if defined(_KERNEL) || defined(_STANDALONE)\r
120 if (endptr)\r
121 *endptr = __UNCONST(nptr);\r
122 return UINTMAX_MAX;\r
123#else\r
124 any = -1;\r
125 acc = UINTMAX_MAX;\r
126 errno = ERANGE;\r
127#endif\r
128 } else {\r
129 any = 1;\r
130 acc *= (uintmax_t)base;\r
131 acc += c;\r
132 }\r
133 }\r
134 if (neg && any > 0)\r
135 acc = (uintmax_t)(-((intmax_t)acc));\r
136 if (endptr != 0)\r
137 *endptr = __UNCONST(any ? s - 1 : nptr);\r
138 return (acc);\r
139}\r