[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[tyndur-devel] [PATCH 4/6] libc: POSIX: strtoul() und strtoull()



+ libc: POSIX: strtoul() und strtoull()
---
 src/include/stdlib.h      |    3 +
 src/lib/stdlibc/strtoul.c |    4 ++
 src/lib/string.c          |   93 ++++++++++++++++++++++++++++++++++++---------
 3 files changed, 82 insertions(+), 18 deletions(-)

diff --git a/src/include/stdlib.h b/src/include/stdlib.h
index 0ecd514..1691441 100644
--- a/src/include/stdlib.h
+++ b/src/include/stdlib.h
@@ -53,6 +53,9 @@ void* realloc(void* address, size_t size);
 void* calloc(size_t size, size_t count);
 void init_memory_manager(void);
 
+unsigned long int strtoul(const char *nptr, char **endptr, int base);
+unsigned long long int strtoull(const char *nptr, char **endptr, int base);
+
 long strtol(const char* str, char** endptr, int base);
 unsigned long strtoul(const char* str, char** endptr, int base);
 char* getenv(const char* name);
diff --git a/src/lib/stdlibc/strtoul.c b/src/lib/stdlibc/strtoul.c
index e3da745..17c82f1 100644
--- a/src/lib/stdlibc/strtoul.c
+++ b/src/lib/stdlibc/strtoul.c
@@ -27,6 +27,8 @@
  * SUCH DAMAGE.
  */
 
+#if 0
+
 #include "limits.h"
 #include "ctype.h"
 #include "errno.h"
@@ -110,3 +112,5 @@ noconv:
 		*endptr = (char *)(any ? s - 1 : nptr);
 	return (acc);
 }
+
+#endif
diff --git a/src/lib/string.c b/src/lib/string.c
index d8e41e6..2f8afdf 100644
--- a/src/lib/string.c
+++ b/src/lib/string.c
@@ -69,27 +69,84 @@ void itoa(unsigned int n, char *s, unsigned int base)
 	}
 	s[y] = '\0';
 }
-unsigned int atoi(const char *s)
+
+unsigned long long int strtoull(const char *nptr, char **endptr, int base)
 {
-	size_t digit = 0;
-	size_t highest = 0;
-	size_t i;
-    for (i=0;s[i] != '\0';i++)
-	{
-		if (s[i] < '0' ||
-			s[i] > '9')break;
-		if (highest == 0)highest = 1;
-		else highest *= 10;
-		digit++;
-	}
-	unsigned int result = 0;
-	for (i=0;i < digit;i++)
-	{
-		result += (s[i] - '0') * highest;
-		highest /= 10;
-	}
+	unsigned long long int result = 0;
+
+    // TODO Vorzeichen
+
+    // Basis feststellen
+    // Bei Basis 16 darf der String mit 0x anfangen
+    // Bei Basis 0 ist automatische Erkennung
+    //   Anfang ist 0x: Basis 16
+    //   Anfang ist 0:  Basis 8
+    //   Ansonsten:     Basis 10
+    switch (base) {
+        case 0:
+            base = 10;
+            if (*nptr == '0') {
+                if (*++nptr == 'x') {
+                    base = 16;
+                    nptr++;
+                } else {
+                    base = 8;
+                }
+            }
+            break;
+
+        case 16:
+            if ((*nptr == '0') && (*(nptr+1) == 'x')) {
+                nptr += 2;
+            }
+            break;
+    }
+
+    // Ergebnis berechnen
+    result = 0;
+    while (*nptr) {
+        switch (*nptr) {
+            case '0' ... '9':
+                if (*nptr - '0' > base - 1) {
+                    goto out;
+                }
+                result = result * base + (*nptr - '0');
+                break;
+            case 'A' ... 'Z':
+                if (*nptr - 'A' + 10 > base - 1) {
+                    goto out;
+                }
+                result = result * base + (*nptr - 'A' + 10);
+                break;
+            case 'a' ... 'z':
+                if (*nptr - 'a' + 10 > base - 1) {
+                    goto out;
+                }
+                result = result * base + (*nptr - 'a' + 10);
+                break;
+        }
+        nptr++;
+    }
+out:
+
+    if (endptr != NULL) {
+        *endptr = (char*) nptr;
+    }
+
 	return result;
 }
+
+unsigned long int strtoul(const char *nptr, char **endptr, int base)
+{
+    return (unsigned long int) strtoull(nptr, endptr, base);
+}
+
+
+unsigned int atoi(const char *s)
+{
+    // FIXME Eigentlich ist atoi ja signed...
+    return (unsigned int) strtoull(s, NULL, 10);
+}
 //
 
 long atol(const char *str)
-- 
1.5.4.5