4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
29 #include "libuutil_common.h"
36 #define IS_DIGIT(x) ((x) >= '0' && (x) <= '9')
38 #define CTOI(x) (((x) >= '0' && (x) <= '9') ? (x) - '0' : \
39 ((x) >= 'a' && (x) <= 'z') ? (x) + 10 - 'a' : (x) + 10 - 'A')
42 strtoint(const char *s_arg
, uint64_t *out
, uint32_t base
, int sign
)
44 const unsigned char *s
= (const unsigned char *)s_arg
;
57 if (s
== NULL
|| base
== 1 || base
> MAX_BASE
) {
58 uu_set_error(UU_ERROR_INVALID_ARGUMENT
);
62 while ((c
= *s
) != 0 && isspace(c
))
68 overflow
= 1; /* becomes underflow below */
79 uu_set_error(UU_ERROR_EMPTY
);
86 else if (s
[1] == 'x' || s
[1] == 'X')
92 if (base
== 16 && c
== '0' && (s
[1] == 'x' || s
[1] == 'X'))
95 if ((val
= CTOI(c
)) >= base
) {
103 multmax
= (uint64_t)UINT64_MAX
/ (uint64_t)base
;
105 for (c
= *++s
; c
!= '\0'; c
= *++s
) {
106 if ((i
= CTOI(c
)) >= base
) {
120 if ((uint64_t)UINT64_MAX
- val
< (uint64_t)i
)
126 while ((c
= *s
) != 0) {
134 if (val
> -(uint64_t)INT64_MIN
)
145 if (bad_char
| bad_digit
| overflow
) {
147 uu_set_error(UU_ERROR_INVALID_CHAR
);
149 uu_set_error(UU_ERROR_INVALID_DIGIT
);
152 uu_set_error(UU_ERROR_UNDERFLOW
);
154 uu_set_error(UU_ERROR_OVERFLOW
);
164 uu_strtoint(const char *s
, void *v
, size_t sz
, int base
,
165 int64_t min
, int64_t max
)
175 if (max
> INT8_MAX
|| min
< INT8_MIN
)
179 if (max
> INT16_MAX
|| min
< INT16_MIN
)
183 if (max
> INT32_MAX
|| min
< INT32_MIN
)
187 if (max
> INT64_MAX
|| min
< INT64_MIN
)
194 if (min
== 0 && max
== 0) {
195 min
= -(1ULL << (8 * sz
- 1));
196 max
= (1ULL << (8 * sz
- 1)) - 1;
199 if (strtoint(s
, &val_u
, base
, 1) == -1)
202 val
= (int64_t)val_u
;
205 uu_set_error(UU_ERROR_UNDERFLOW
);
207 } else if (val
> max
) {
208 uu_set_error(UU_ERROR_OVERFLOW
);
226 break; /* fall through to bad_argument */
230 uu_set_error(UU_ERROR_INVALID_ARGUMENT
);
235 uu_strtouint(const char *s
, void *v
, size_t sz
, int base
,
236 uint64_t min
, uint64_t max
)
249 if (max
> UINT16_MAX
)
253 if (max
> UINT32_MAX
)
257 if (max
> UINT64_MAX
)
264 if (min
== 0 && max
== 0) {
265 /* we have to be careful, since << can overflow */
266 max
= (1ULL << (8 * sz
- 1)) * 2 - 1;
269 if (strtoint(s
, &val
, base
, 0) == -1)
273 uu_set_error(UU_ERROR_UNDERFLOW
);
275 } else if (val
> max
) {
276 uu_set_error(UU_ERROR_OVERFLOW
);
285 *(uint16_t *)v
= val
;
288 *(uint32_t *)v
= val
;
291 *(uint64_t *)v
= val
;
294 break; /* shouldn't happen, fall through */
298 uu_set_error(UU_ERROR_INVALID_ARGUMENT
);