libutil

C Utility Library
git clone http://git.omkov.net/libutil
Log | Tree | Refs | README | LICENCE | Download

AuthorJamozed <[email protected]>
Date2021-02-21 10:23:02
Commit99202e8d665be591e9f50fa3e332206df0dbf58f
Parent4e919ee8994d6d2bfee6963cceaa936d26fd4260

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