[PATCH 1/3] libwine: Add strtoullW.

Daniel Lehman dlehman25 at gmail.com
Mon Aug 26 23:30:02 CDT 2019


Signed-off-by: Daniel Lehman <dlehman25 at gmail.com>
---
 include/wine/unicode.h |   1 +
 libs/port/string.c     | 113 +++++++++++++++++++++++++++++++++++++++++
 libs/wine/wine.map     |   1 +
 3 files changed, 115 insertions(+)

diff --git a/include/wine/unicode.h b/include/wine/unicode.h
index ff6f6568a5..5ee53e74a5 100644
--- a/include/wine/unicode.h
+++ b/include/wine/unicode.h
@@ -108,6 +108,7 @@ extern int memicmpW( const WCHAR *str1, const WCHAR *str2, int n );
 extern WCHAR *strstrW( const WCHAR *str, const WCHAR *sub );
 extern long int strtolW( const WCHAR *nptr, WCHAR **endptr, int base );
 extern unsigned long int strtoulW( const WCHAR *nptr, WCHAR **endptr, int base );
+extern unsigned long long strtoullW( const WCHAR *nptr, WCHAR **endptr, int base );
 extern int sprintfW( WCHAR *str, const WCHAR *format, ... );
 extern int snprintfW( WCHAR *str, size_t len, const WCHAR *format, ... );
 extern int vsprintfW( WCHAR *str, const WCHAR *format, va_list valist );
diff --git a/libs/port/string.c b/libs/port/string.c
index c3388bcc7d..0ff4700664 100644
--- a/libs/port/string.c
+++ b/libs/port/string.c
@@ -301,6 +301,119 @@ noconv:
 }
 
 
+unsigned long long strtoullW( const WCHAR *nptr, WCHAR **endptr, int base )
+{
+  int negative;
+  register unsigned long long cutoff;
+  register unsigned int cutlim;
+  register unsigned long long i;
+  register const WCHAR *s;
+  register WCHAR c;
+  const WCHAR *save, *end;
+  int overflow;
+
+  if (base < 0 || base == 1 || base > 36) return 0;
+
+  save = s = nptr;
+
+  /* Skip white space.  */
+  while (isspaceW (*s))
+    ++s;
+  if (!*s) goto noconv;
+
+  /* Check for a sign.  */
+  negative = 0;
+  if (*s == '-')
+    {
+      negative = 1;
+      ++s;
+    }
+  else if (*s == '+')
+    ++s;
+
+  /* Recognize number prefix and if BASE is zero, figure it out ourselves.  */
+  if (*s == '0')
+    {
+      if ((base == 0 || base == 16) && toupperW(s[1]) == 'X')
+	{
+	  s += 2;
+	  base = 16;
+	}
+      else if (base == 0)
+	base = 8;
+    }
+  else if (base == 0)
+    base = 10;
+
+  /* Save the pointer so we can check later if anything happened.  */
+  save = s;
+  end = NULL;
+
+  cutoff = ULLONG_MAX / (unsigned long long) base;
+  cutlim = ULLONG_MAX % (unsigned long long) base;
+
+  overflow = 0;
+  i = 0;
+  c = *s;
+  for (;c != '\0'; c = *++s)
+  {
+      if (s == end)
+          break;
+      if (c >= '0' && c <= '9')
+          c -= '0';
+      else if (isalphaW (c))
+          c = toupperW (c) - 'A' + 10;
+      else
+          break;
+      if ((int) c >= base)
+          break;
+      /* Check for overflow.  */
+      if (i > cutoff || (i == cutoff && c > cutlim))
+          overflow = 1;
+      else
+      {
+          i *= (unsigned long long) base;
+          i += c;
+      }
+  }
+
+  /* Check if anything actually happened.  */
+  if (s == save)
+    goto noconv;
+
+  /* Store in ENDPTR the address of one character
+     past the last character we converted.  */
+  if (endptr != NULL)
+    *endptr = (WCHAR *)s;
+
+  if (overflow)
+    {
+      errno = ERANGE;
+      return ULLONG_MAX;
+    }
+
+  /* Return the result of the appropriate sign.  */
+  return negative ? -i : i;
+
+noconv:
+  /* We must handle a special case here: the base is 0 or 16 and the
+     first two characters are '0' and 'x', but the rest are not
+     hexadecimal digits.  This is no error case.  We return 0 and
+     ENDPTR points to the `x`.  */
+  if (endptr != NULL)
+    {
+      if (save - nptr >= 2 && toupperW (save[-1]) == 'X'
+	  && save[-2] == '0')
+	*endptr = (WCHAR *)&save[-1];
+      else
+	/*  There was no number to convert.  */
+	*endptr = (WCHAR *)nptr;
+    }
+
+  return 0;
+}
+
+
 /* format a WCHAR string according to a printf format; helper for vsnprintfW */
 static size_t format_string( WCHAR *buffer, size_t len, const char *format, const WCHAR *str, int str_len )
 {
diff --git a/libs/wine/wine.map b/libs/wine/wine.map
index 2159fac852..741ae759de 100644
--- a/libs/wine/wine.map
+++ b/libs/wine/wine.map
@@ -44,6 +44,7 @@ WINE_1.0
     strstrW;
     strtolW;
     strtoulW;
+    strtoullW;
     struprW;
     tolowerW;
     toupperW;
-- 
2.17.1




More information about the wine-devel mailing list