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

[Minios-devel] [UNIKRAFT PATCH 4/5] lib/nolibc: Add strtoq and strtouq functions


  • To: minios-devel@xxxxxxxxxxxxx
  • From: Costin Lupu <costin.lupu@xxxxxxxxx>
  • Date: Tue, 3 Jul 2018 10:04:16 +0300
  • Cc: simon.kuenzer@xxxxxxxxx, sharan.santhanam@xxxxxxxxx, yuri.volchkov@xxxxxxxxx
  • Delivery-date: Tue, 03 Jul 2018 07:04:31 +0000
  • Ironport-phdr: 9a23:o9LrgR0nrKzWgiTKsmDT+DRfVm0co7zxezQtwd8ZseMVLPad9pjvdHbS+e9qxAeQG9mDtbQc06L/iOPJYSQ4+5GPsXQPItRndiQuroEopTEmG9OPEkbhLfTnPGQQFcVGU0J5rTngaRAGUMnxaEfPrXKs8DUcBgvwNRZvJuTyB4Xek9m72/q99pHPYghEniaxba9vJxiqsAvdsdUbj5F/Iagr0BvJpXVIe+VSxWx2IF+Yggjx6MSt8pN96ipco/0u+dJOXqX8ZKQ4UKdXDC86PGAv5c3krgfMQA2S7XYBSGoWkx5IAw/Y7BHmW5r6ryX3uvZh1CScIMb7S60/Vza/4KdxUBLmiDkJOSM3/m/UjcJ/jqxbrQm9qxBj2YPYfJuYOOZicq7bYNgURXBBXsFUVyFZHI68aJAPD/YAPeZesoLzoUYOrQOjBQKxA+7g1jhIhmTq3a071eQtCwXG3BE4H9ITq3nbsM71OL0KUeCo16bE1y/Db/RP1Dr79YPGcQghrOmRUb9/bMbd00oiGgPfglmOt4DoPSmZ2+oVv2SG4OdsSPijhm0npg1rvDSiyMkhhpPUio8a1FzJ8zhyzpwvKt2iUkF7ZMapEJ5Xty6HKYR7WtgiQ2R0uCYizb0GpIK7cDAKyJs5wx7fbOSKc5aN4h35VeaRJS10i25+eL6lnxay7FOvxvfmVsmzyFpKryxFncfQtn0VyhDe5dWLRuF+80qhwzqDyR7f5+NeLU06jabbLoQuwr80lpodq0TDGSr2lV3qg6+RbUUk5umo6+L9brXiu5+cL5J0hxriPaQ1gMC/Gfk4PRMUU2iB/uSwzKfj8lHhQLVWkv02lbHUsJXbJcQdp665BBRV3p8+5BmhETepztAYkGIDLFJEYxKHk5PpN0vBIf/mC/ezmVOskC1kx/reJL3uHo3NLmTfkLfmZbt98E5cxxApzd9F4ZJYEKoBL+j1Wk/ttNzXFBk5PBaxw+v8DtVyyJ8RWWaVDaCCKq/dr0KI7Po1I+aQfI8VpCr9K/896v71jH85nFgdfa+z0ZsUdXC3APJmIkSHbnr2mdoBF3kFsRY6TOPwk1KOSyBcZ2uqVaIm+j47EJ6mDZvERo21gL2BwT27HpxMamBYDVCMFWvnd4WHW/cLdiKfOclhnSIYWrilUYAuzguiuxHny+kvEu2B/ywetJX4kdR4+eDXvRUz7iBvSdSQ1SeKVW4nsHkPQmod27tjoEo17kqbzOAsiPtDCd1VofdUShoSPoWa1/FwTcr1DFGSNuyVQUqrF431SQo6Scg8locD
  • List-id: Mini-os development list <minios-devel.lists.xenproject.org>

These functions are needed by vsscanf function.
Shamelessly taken from Mini-OS.

Signed-off-by: Costin Lupu <costin.lupu@xxxxxxxxx>
---
 lib/nolibc/include/stdlib.h |  16 +++++
 lib/nolibc/stdlib.c         | 147 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 163 insertions(+)

diff --git a/lib/nolibc/include/stdlib.h b/lib/nolibc/include/stdlib.h
index f2a0ccf..6c50ab1 100644
--- a/lib/nolibc/include/stdlib.h
+++ b/lib/nolibc/include/stdlib.h
@@ -48,6 +48,22 @@ unsigned long strtoul(const char *nptr, char **endptr, int 
base);
 long long strtoll(const char *nptr, char **endptr, int base);
 unsigned long long strtoull(const char *nptr, char **endptr, int base);
 
+/*
+ * Convert a string to a quad integer.
+ *
+ * Ignores `locale' stuff.  Assumes that the upper and lower case
+ * alphabets and digits are each contiguous.
+ */
+int64_t strtoq(const char *nptr, char **endptr, int base);
+
+/*
+ * Convert a string to an unsigned quad integer.
+ *
+ * Ignores `locale' stuff.  Assumes that the upper and lower case
+ * alphabets and digits are each contiguous.
+ */
+uint64_t strtouq(const char *nptr, char **endptr, int base);
+
 /**
  * Convert a string to an integer
  * @s: The start of the string
diff --git a/lib/nolibc/stdlib.c b/lib/nolibc/stdlib.c
index 3e12620..53a3f11 100644
--- a/lib/nolibc/stdlib.c
+++ b/lib/nolibc/stdlib.c
@@ -275,6 +275,153 @@ unsigned long long strtoull(const char *nptr, char 
**endptr, int base)
        return acc;
 }
 
+int64_t strtoq(const char *nptr, char **endptr, int base)
+{
+       const char *s;
+       uint64_t acc;
+       unsigned char c;
+       uint64_t qbase, cutoff;
+       int neg, any, cutlim;
+
+       /*
+        * Skip white space and pick up leading +/- sign if any.
+        * If base is 0, allow 0x for hex and 0 for octal, else
+        * assume decimal; if base is already 16, allow 0x.
+        */
+       s = nptr;
+       do {
+               c = *s++;
+       } while (isspace(c));
+       if (c == '-') {
+               neg = 1;
+               c = *s++;
+       } else {
+               neg = 0;
+               if (c == '+')
+                       c = *s++;
+       }
+       if ((base == 0 || base == 16) &&
+               c == '0' && (*s == 'x' || *s == 'X')) {
+               c = s[1];
+               s += 2;
+               base = 16;
+       }
+       if (base == 0)
+               base = c == '0' ? 8 : 10;
+
+       /*
+        * Compute the cutoff value between legal numbers and illegal
+        * numbers.  That is the largest legal value, divided by the
+        * base.  An input number that is greater than this value, if
+        * followed by a legal input character, is too big.  One that
+        * is equal to this value may be valid or not; the limit
+        * between valid and invalid numbers is then based on the last
+        * digit.  For instance, if the range for quads is
+        * [-9223372036854775808..9223372036854775807] and the input base
+        * is 10, cutoff will be set to 922337203685477580 and cutlim to
+        * either 7 (neg==0) or 8 (neg==1), meaning that if we have
+        * accumulated a value > 922337203685477580, or equal but the
+        * next digit is > 7 (or 8), the number is too big, and we will
+        * return a range error.
+        *
+        * Set any if any `digits' consumed; make it negative to indicate
+        * overflow.
+        */
+       qbase = (unsigned int) base;
+       cutoff = neg
+               ? (uint64_t) -(LLONG_MIN + LLONG_MAX) + LLONG_MAX
+               : LLONG_MAX;
+       cutlim = cutoff % qbase;
+       cutoff /= qbase;
+       for (acc = 0, any = 0;; c = *s++) {
+               if (!isascii(c))
+                       break;
+               if (isdigit(c))
+                       c -= '0';
+               else if (isalpha(c))
+                       c -= isupper(c) ? 'A' - 10 : 'a' - 10;
+               else
+                       break;
+               if (c >= base)
+                       break;
+               if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
+                       any = -1;
+               else {
+                       any = 1;
+                       acc *= qbase;
+                       acc += c;
+               }
+       }
+       if (any < 0)
+               acc = neg ? LLONG_MIN : LLONG_MAX;
+       else if (neg)
+               acc = -acc;
+       if (endptr != 0)
+               *endptr = __DECONST(char *, any ? s - 1 : nptr);
+       return acc;
+}
+
+uint64_t strtouq(const char *nptr, char **endptr, int base)
+{
+       const char *s = nptr;
+       uint64_t acc;
+       unsigned char c;
+       uint64_t qbase, cutoff;
+       int neg, any, cutlim;
+
+       /*
+        * See strtoq for comments as to the logic used.
+        */
+       do {
+               c = *s++;
+       } while (isspace(c));
+       if (c == '-') {
+               neg = 1;
+               c = *s++;
+       } else {
+               neg = 0;
+               if (c == '+')
+                       c = *s++;
+       }
+       if ((base == 0 || base == 16) &&
+               c == '0' && (*s == 'x' || *s == 'X')) {
+               c = s[1];
+               s += 2;
+               base = 16;
+       }
+       if (base == 0)
+               base = c == '0' ? 8 : 10;
+       qbase = (unsigned int) base;
+       cutoff = (uint64_t) ULLONG_MAX / qbase;
+       cutlim = (uint64_t) ULLONG_MAX % qbase;
+       for (acc = 0, any = 0;; c = *s++) {
+               if (!isascii(c))
+                       break;
+               if (isdigit(c))
+                       c -= '0';
+               else if (isalpha(c))
+                       c -= isupper(c) ? 'A' - 10 : 'a' - 10;
+               else
+                       break;
+               if (c >= base)
+                       break;
+               if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
+                       any = -1;
+               else {
+                       any = 1;
+                       acc *= qbase;
+                       acc += c;
+               }
+       }
+       if (any < 0)
+               acc = ULLONG_MAX;
+       else if (neg)
+               acc = -acc;
+       if (endptr != 0)
+               *endptr = __DECONST(char *, any ? s - 1 : nptr);
+       return acc;
+}
+
 int atoi(const char *s)
 {
        long long atoll;
-- 
2.11.0


_______________________________________________
Minios-devel mailing list
Minios-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/minios-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.