diff mbox series

[kvm-unit-tests,2/2] lib: Introduce strtoll/strtoull

Message ID 20211013164259.88281-3-drjones@redhat.com (mailing list archive)
State New, archived
Headers show
Series Introduce strtoll/strtoull | expand

Commit Message

Andrew Jones Oct. 13, 2021, 4:42 p.m. UTC
Signed-off-by: Andrew Jones <drjones@redhat.com>
---
 lib/stdlib.h |  2 ++
 lib/string.c | 51 +++++++++++++++++++++++++++++++++++++--------------
 2 files changed, 39 insertions(+), 14 deletions(-)

Comments

Ahmed, Daniele Oct. 14, 2021, 9:45 a.m. UTC | #1
Reviewed-by: Daniele Ahmed <ahmeddan@amazon.com>




Amazon Development Center Germany GmbH
Krausenstr. 38
10117 Berlin
Geschaeftsfuehrung: Christian Schlaeger, Jonathan Weiss
Eingetragen am Amtsgericht Charlottenburg unter HRB 149173 B
Sitz: Berlin
Ust-ID: DE 289 237 879
diff mbox series

Patch

diff --git a/lib/stdlib.h b/lib/stdlib.h
index 33c00e8a5204..28496d7ae333 100644
--- a/lib/stdlib.h
+++ b/lib/stdlib.h
@@ -9,5 +9,7 @@ 
 
 long int strtol(const char *nptr, char **endptr, int base);
 unsigned long int strtoul(const char *nptr, char **endptr, int base);
+long long int strtoll(const char *nptr, char **endptr, int base);
+unsigned long long int strtoull(const char *nptr, char **endptr, int base);
 
 #endif /* _STDLIB_H_ */
diff --git a/lib/string.c b/lib/string.c
index ffc7c7e4f855..27106dae0b0b 100644
--- a/lib/string.c
+++ b/lib/string.c
@@ -168,9 +168,10 @@  static int isspace(int c)
     return c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == '\v' || c == '\f';
 }
 
-static unsigned long __strtol(const char *nptr, char **endptr,
-                              int base, bool is_signed) {
-    unsigned long acc = 0;
+static unsigned long long __strtoll(const char *nptr, char **endptr,
+                                    int base, bool is_signed,
+                                    bool is_longlong) {
+    unsigned long long ull = 0;
     const char *s = nptr;
     int neg, c;
 
@@ -210,36 +211,58 @@  static unsigned long __strtol(const char *nptr, char **endptr,
         else
             break;
 
-        if (is_signed) {
-            long sacc = (long)acc;
-            assert(!check_mul_overflow(sacc, base));
-            assert(!check_add_overflow(sacc * base, c));
+        if (!is_longlong) {
+            if (is_signed) {
+                long sl = (long)ull;
+                assert(!check_mul_overflow(sl, base));
+                assert(!check_add_overflow(sl * base, c));
+            } else {
+                unsigned long ul = (unsigned long)ull;
+                assert(!check_mul_overflow(ul, base));
+                assert(!check_add_overflow(ul * base, c));
+            }
         } else {
-            assert(!check_mul_overflow(acc, base));
-            assert(!check_add_overflow(acc * base, c));
+            if (is_signed) {
+                long long sll = (long long)ull;
+                assert(!check_mul_overflow(sll, base));
+                assert(!check_add_overflow(sll * base, c));
+            } else {
+                assert(!check_mul_overflow(ull, base));
+                assert(!check_add_overflow(ull * base, c));
+            }
         }
 
-        acc = acc * base + c;
+        ull = ull * base + c;
         s++;
     }
 
     if (neg)
-        acc = -acc;
+        ull = -ull;
 
     if (endptr)
         *endptr = (char *)s;
 
-    return acc;
+    return ull;
 }
 
 long int strtol(const char *nptr, char **endptr, int base)
 {
-    return __strtol(nptr, endptr, base, true);
+    return __strtoll(nptr, endptr, base, true, false);
 }
 
 unsigned long int strtoul(const char *nptr, char **endptr, int base)
 {
-    return __strtol(nptr, endptr, base, false);
+    return __strtoll(nptr, endptr, base, false, false);
+}
+
+long long int strtoll(const char *nptr, char **endptr, int base)
+{
+    return __strtoll(nptr, endptr, base, true, true);
+}
+
+unsigned long long int strtoull(const char *nptr, char **endptr, int base)
+{
+    return __strtoll(nptr, endptr, base, false, true);
 }
 
 long atol(const char *ptr)