16691 zfstest: rootpool tests do not make sense when rootfs is not zfs
[illumos-gate.git] / usr / src / common / util / strtoul.c
blobc2bbde243eebd88efe4f35b5dbcf41608b3af1ec
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 /* Copyright (c) 1988 AT&T */
28 /* All Rights Reserved */
30 #if defined(_KERNEL)
31 #include <sys/null.h>
32 #endif /* _KERNEL */
34 #if defined(_KERNEL) && !defined(_BOOT)
35 #include <sys/errno.h>
36 #else /* _KERNEL && !_BOOT */
37 #if !defined(_BOOT) && !defined(_KMDB) && !defined(_STANDALONE)
38 #include "lint.h"
39 #endif /* !_BOOT && !_KMDB && !_STANDALONE */
40 #if defined(_STANDALONE)
41 #include <sys/cdefs.h>
42 #include <stand.h>
43 #include <limits.h>
44 #else
45 #include <errno.h>
46 #include <ctype.h>
47 #include <limits.h>
48 #include <stdlib.h>
49 #endif /* _STANDALONE */
50 #endif /* _KERNEL && !_BOOT */
51 #include "strtolctype.h"
52 #include <sys/types.h>
54 #if defined(_KERNEL) && !defined(_BOOT)
55 int
56 ddi_strtoul(const char *str, char **nptr, int base, unsigned long *result)
57 #else /* _KERNEL && !_BOOT */
58 unsigned long
59 strtoul(const char *str, char **nptr, int base)
60 #endif /* _KERNEL && !_BOOT */
62 unsigned long val;
63 int c;
64 int xx;
65 int neg = 0;
66 unsigned long multmax;
67 const char **ptr = (const char **)nptr;
68 const unsigned char *ustr = (const unsigned char *)str;
70 if (ptr != NULL)
71 *ptr = (char *)ustr; /* in case no number is formed */
72 if (base < 0 || base > MBASE || base == 1) {
73 /* base is invalid -- should be a fatal error */
74 #if defined(_KERNEL) && !defined(_BOOT)
75 return (EINVAL);
76 #else /* _KERNEL && !_BOOT */
77 errno = EINVAL;
78 return (0);
79 #endif /* _KERNEL && !_BOOT */
81 if (!isalnum(c = *ustr)) {
82 while (isspace(c))
83 c = *++ustr;
84 switch (c) {
85 case '-':
86 neg++;
87 /* FALLTHROUGH */
88 case '+':
89 c = *++ustr;
92 if (base == 0) {
93 if (c != '0')
94 base = 10;
95 else if (ustr[1] == 'x' || ustr[1] == 'X')
96 base = 16;
97 else
98 base = 8;
101 * for any base > 10, the digits incrementally following
102 * 9 are assumed to be "abc...z" or "ABC...Z"
104 if (!lisalnum(c) || (xx = DIGIT(c)) >= base) {
105 /* no number formed */
106 #if defined(_KERNEL) && !defined(_BOOT)
107 return (EINVAL);
108 #else /* _KERNEL && !_BOOT */
109 return (0);
110 #endif /* _KERNEL && !_BOOT */
112 if (base == 16 && c == '0' && (ustr[1] == 'x' || ustr[1] == 'X') &&
113 isxdigit(ustr[2]))
114 c = *(ustr += 2); /* skip over leading "0x" or "0X" */
116 multmax = ULONG_MAX / (unsigned long)base;
117 val = DIGIT(c);
118 for (c = *++ustr; lisalnum(c) && (xx = DIGIT(c)) < base; ) {
119 if (val > multmax)
120 goto overflow;
121 val *= base;
122 if (ULONG_MAX - val < (unsigned long)xx)
123 goto overflow;
124 val += xx;
125 c = *++ustr;
127 if (ptr != NULL)
128 *ptr = (char *)ustr;
129 #if defined(_KERNEL) && !defined(_BOOT)
130 *result = neg ? -val : val;
131 return (0);
132 #else /* _KERNEL && !_BOOT */
133 return (neg ? -val : val);
134 #endif /* _KERNEL && !_BOOT */
136 overflow:
137 for (c = *++ustr; lisalnum(c) && (xx = DIGIT(c)) < base; (c = *++ustr))
139 if (ptr != NULL)
140 *ptr = (char *)ustr;
141 #if defined(_KERNEL) && !defined(_BOOT)
142 return (ERANGE);
143 #else /* _KERNEL && !_BOOT */
144 errno = ERANGE;
145 return (ULONG_MAX);
146 #endif /* _KERNEL && !_BOOT */