Author | Jamozed <[email protected]> |
Date | 2021-02-21 10:23:02 |
Commit | 99202e8d665be591e9f50fa3e332206df0dbf58f |
Parent | 4e919ee8994d6d2bfee6963cceaa936d26fd4260 |
strconv: Add strconv
Implement string to unsigned integer conversion functions
Diffstat
A | src/strconv.c | | | 163 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | src/strconv.h | | | 43 | +++++++++++++++++++++++++++++++++++++++++++ |
2 files changed, 206 insertions, 0 deletions
diff --git a/src/strconv.c b/src/strconv.c new file mode 100644 index 0000000..7e9afa8 --- /dev/null +++ b/src/strconv.c @@ -0,0 +1,163 @@ +// strconv.c, version 1.0.0 +// String conversion source file for OMKOV lib +// Copyright (C) 2021, Jakob Wakeling +// All rights reserved. + +/* +OMKOV Permissive Licence, version 1.0 + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal with +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimers. +* Redistributions in binary form must reproduce the above copyright notice, this + list of conditions and the following disclaimers in the documentation and/or + other materials provided with the distribution. +* Neither the names of the copyright holders, nor the names of its contributors + may be used to endorse or promote products derived from this Software without + specific prior written permission. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT +HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE. +*/ + +#include <ctype.h> +#include <errno.h> +#include <stdint.h> + +/* Convert a string to an unsigned 8-bit integer */ +uint8_t strtou8(const char *nptr, char **endptr, register int base) { + register const char *s = nptr; register uint8_t i = 0, c; + + for (; isspace(*s); ++s); + + if (*s == '+') { ++s; } else if (*s == '-') { errno = EINVAL; goto end; } + + if ((!base || base == 16) && s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) { + s += 2; base = 16; + } + else if (base == 0) { base = s[0] == '0' ? 8 : 10; } + else if (base < 2 || base > 36) { errno = EINVAL; goto end; } + + for (;; ++s) { + if (*s >= '0' && *s <= '9') { c = *s - '0'; } + else if (*s >= 'A' && *s <= 'Z') { c = *s - ('A' - 10); } + else if (*s >= 'a' && *s <= 'z') { c = *s - ('a' - 10); } + else { break; } + + if (c >= base) { break; } + if (i > (UINT8_MAX - c) / base) { + errno = ERANGE; i = UINT8_MAX; goto end; + } + + i = i * base + c; + } + +end:; + if (endptr) { *endptr = (char *)s; } return i; +} + +/* Convert a string to an unsigned 16-bit integer */ +uint16_t strtou16(const char *nptr, char **endptr, register int base) { + register const char *s = nptr; register uint16_t i = 0, c; + + for (; isspace(*s); ++s); + + if (*s == '+') { ++s; } else if (*s == '-') { errno = EINVAL; goto end; } + + if ((!base || base == 16) && s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) { + s += 2; base = 16; + } + else if (base == 0) { base = s[0] == '0' ? 8 : 10; } + else if (base < 2 || base > 36) { errno = EINVAL; goto end; } + + for (;; ++s) { + if (*s >= '0' && *s <= '9') { c = *s - '0'; } + else if (*s >= 'A' && *s <= 'Z') { c = *s - ('A' - 10); } + else if (*s >= 'a' && *s <= 'z') { c = *s - ('a' - 10); } + else { break; } + + if (c >= base) { break; } + if (i > (UINT16_MAX - c) / base) { + errno = ERANGE; i = UINT16_MAX; goto end; + } + + i = i * base + c; + } + +end:; + if (endptr) { *endptr = (char *)s; } return i; +} + +/* Convert a string to an unsigned 32-bit integer */ +uint32_t strtou32(const char *nptr, char **endptr, register int base) { + register const char *s = nptr; register uint32_t i = 0, c; + + for (; isspace(*s); ++s); + + if (*s == '+') { ++s; } else if (*s == '-') { errno = EINVAL; goto end; } + + if ((!base || base == 16) && s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) { + s += 2; base = 16; + } + else if (base == 0) { base = s[0] == '0' ? 8 : 10; } + else if (base < 2 || base > 36) { errno = EINVAL; goto end; } + + for (;; ++s) { + if (*s >= '0' && *s <= '9') { c = *s - '0'; } + else if (*s >= 'A' && *s <= 'Z') { c = *s - ('A' - 10); } + else if (*s >= 'a' && *s <= 'z') { c = *s - ('a' - 10); } + else { break; } + + if (c >= base) { break; } + if (i > (UINT32_MAX - c) / base) { + errno = ERANGE; i = UINT32_MAX; goto end; + } + + i = i * base + c; + } + +end:; + if (endptr) { *endptr = (char *)s; } return i; +} + +/* Convert a string to an unsigned 64-bit integer */ +uint64_t strtou64(const char *nptr, char **endptr, register int base) { + register const char *s = nptr; register uint64_t i = 0, c; + + for (; isspace(*s); ++s); + + if (*s == '+') { ++s; } else if (*s == '-') { errno = EINVAL; goto end; } + + if ((!base || base == 16) && s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) { + s += 2; base = 16; + } + else if (base == 0) { base = s[0] == '0' ? 8 : 10; } + else if (base < 2 || base > 36) { errno = EINVAL; goto end; } + + for (;; ++s) { + if (*s >= '0' && *s <= '9') { c = *s - '0'; } + else if (*s >= 'A' && *s <= 'Z') { c = *s - ('A' - 10); } + else if (*s >= 'a' && *s <= 'z') { c = *s - ('a' - 10); } + else { break; } + + if (c >= base) { break; } + if (i > (UINT64_MAX - c) / base) { + errno = ERANGE; i = UINT64_MAX; goto end; + } + + i = i * base + c; + } + +end:; + if (endptr) { *endptr = (char *)s; } return i; +} diff --git a/src/strconv.h b/src/strconv.h new file mode 100644 index 0000000..182e322 --- /dev/null +++ b/src/strconv.h @@ -0,0 +1,43 @@ +// strconv.h, version 1.0.0 +// String conversion header file for OMKOV lib +// Copyright (C) 2020, Jakob Wakeling +// All rights reserved. + +/* +OMKOV Permissive Licence, version 1.0 + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal with +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimers. +* Redistributions in binary form must reproduce the above copyright notice, this + list of conditions and the following disclaimers in the documentation and/or + other materials provided with the distribution. +* Neither the names of the copyright holders, nor the names of its contributors + may be used to endorse or promote products derived from this Software without + specific prior written permission. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT +HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE. +*/ + +#ifndef OMKOV_LIB_STRING_H_3EQMSZZK +#define OMKOV_LIB_STRING_H_3EQMSZZK + +#include <stdint.h> + +uint8_t strtou8(const char *nptr, char **endptr, register int base); +uint16_t strtou16(const char *nptr, char **endptr, register int base); +uint32_t strtou32(const char *nptr, char **endptr, register int base); +uint64_t strtou64(const char *nptr, char **endptr, register int base); + +#endif // OMKOV_LIB_STRING_H_3EQMSZZK