diff options
Diffstat (limited to 'usr/src/common/util/strtoul.c')
| -rw-r--r-- | usr/src/common/util/strtoul.c | 62 |
1 files changed, 38 insertions, 24 deletions
diff --git a/usr/src/common/util/strtoul.c b/usr/src/common/util/strtoul.c index 9d01f2eebf..3b1eff90c1 100644 --- a/usr/src/common/util/strtoul.c +++ b/usr/src/common/util/strtoul.c @@ -20,54 +20,53 @@ */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* Copyright (c) 1988 AT&T */ /* All Rights Reserved */ -#pragma ident "%Z%%M% %I% %E% SMI" - -#if !defined(_BOOT) && !defined(_KMDB) +#if defined(_KERNEL) && !defined(_BOOT) +#include <sys/errno.h> +#else /* _KERNEL && !_BOOT */ +#if !defined(_BOOT) && !defined(_KMDB) #include "lint.h" -#endif /* !_BOOT && !_KMDB */ +#endif /* !_BOOT && !_KMDB */ #include <errno.h> #include <ctype.h> #include <limits.h> #include <stdlib.h> +#endif /* _KERNEL && !_BOOT */ +#include "strtolctype.h" #include <sys/types.h> -#define DIGIT(x) \ - (isdigit(x) ? (x) - '0' : islower(x) ? (x) + 10 - 'a' : (x) + 10 - 'A') - -#define MBASE ('z' - 'a' + 1 + 10) - -/* - * The following macro is a local version of isalnum() which limits - * alphabetic characters to the ranges a-z and A-Z; locale dependent - * characters will not return 1. The members of a-z and A-Z are - * assumed to be in ascending order and contiguous - */ -#define lisalnum(x) \ - (isdigit(x) || ((x) >= 'a' && (x) <= 'z') || ((x) >= 'A' && (x) <= 'Z')) - +#if defined(_KERNEL) && !defined(_BOOT) +int +ddi_strtoul(const char *str, char **nptr, int base, unsigned long *result) +#else /* _KERNEL && !_BOOT */ unsigned long strtoul(const char *str, char **nptr, int base) +#endif /* _KERNEL && !_BOOT */ { unsigned long val; int c; int xx; - unsigned long multmax; int neg = 0; + unsigned long multmax; const char **ptr = (const char **)nptr; - const unsigned char *ustr = (const unsigned char *)str; + const unsigned char *ustr = (const unsigned char *)str; if (ptr != (const char **)0) *ptr = (char *)ustr; /* in case no number is formed */ if (base < 0 || base > MBASE || base == 1) { + /* base is invalid -- should be a fatal error */ +#if defined(_KERNEL) && !defined(_BOOT) + return (EINVAL); +#else /* _KERNEL && !_BOOT */ errno = EINVAL; - return (0); /* base is invalid -- should be a fatal error */ + return (0); +#endif /* _KERNEL && !_BOOT */ } if (!isalnum(c = *ustr)) { while (isspace(c)) @@ -91,8 +90,14 @@ strtoul(const char *str, char **nptr, int base) * for any base > 10, the digits incrementally following * 9 are assumed to be "abc...z" or "ABC...Z" */ - if (!lisalnum(c) || (xx = DIGIT(c)) >= base) - return (0); /* no number formed */ + if (!lisalnum(c) || (xx = DIGIT(c)) >= base) { + /* no number formed */ +#if defined(_KERNEL) && !defined(_BOOT) + return (EINVAL); +#else /* _KERNEL && !_BOOT */ + return (0); +#endif /* _KERNEL && !_BOOT */ + } if (base == 16 && c == '0' && (ustr[1] == 'x' || ustr[1] == 'X') && isxdigit(ustr[2])) c = *(ustr += 2); /* skip over leading "0x" or "0X" */ @@ -110,13 +115,22 @@ strtoul(const char *str, char **nptr, int base) } if (ptr != (const char **)0) *ptr = (char *)ustr; +#if defined(_KERNEL) && !defined(_BOOT) + *result = neg ? -val : val; + return (0); +#else /* _KERNEL && !_BOOT */ return (neg ? -val : val); +#endif /* _KERNEL && !_BOOT */ overflow: for (c = *++ustr; lisalnum(c) && (xx = DIGIT(c)) < base; (c = *++ustr)) ; if (ptr != (const char **)0) *ptr = (char *)ustr; +#if defined(_KERNEL) && !defined(_BOOT) + return (ERANGE); +#else /* _KERNEL && !_BOOT */ errno = ERANGE; return (ULONG_MAX); +#endif /* _KERNEL && !_BOOT */ } |
