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

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

 



Signed-off-by: Andrew Jones <drjones@xxxxxxxxxx>
---
 lib/stdlib.h |  2 ++
 lib/string.c | 51 +++++++++++++++++++++++++++++++++++++--------------
 2 files changed, 39 insertions(+), 14 deletions(-)

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)
-- 
2.31.1




[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux