Share more duplicated functions
Modified: trunk/reactos/include/ndk/rtlfuncs.h
Modified: trunk/reactos/lib/ntdll/ntdll.xml
Deleted: trunk/reactos/lib/ntdll/stdlib/
Added: trunk/reactos/lib/string/abs.c
Added: trunk/reactos/lib/string/atoi.c
Added: trunk/reactos/lib/string/atoi64.c
Added: trunk/reactos/lib/string/atol.c
Added: trunk/reactos/lib/string/bsearch.c
Added: trunk/reactos/lib/string/itoa.c
Added: trunk/reactos/lib/string/itow.c
Added: trunk/reactos/lib/string/labs.c
Added: trunk/reactos/lib/string/lfind.c
Added: trunk/reactos/lib/string/mbstowcs.c
Added: trunk/reactos/lib/string/rand.c
Added: trunk/reactos/lib/string/splitp.c
Modified: trunk/reactos/lib/string/string.xml
Added: trunk/reactos/lib/string/strtol.c
Added: trunk/reactos/lib/string/strtoul.c
Added: trunk/reactos/lib/string/wcstol.c
Added: trunk/reactos/lib/string/wcstombs.c
Added: trunk/reactos/lib/string/wcstoul.c
Added: trunk/reactos/lib/string/wtoi.c
Added: trunk/reactos/lib/string/wtoi64.c
Added: trunk/reactos/lib/string/wtol.c
Modified: trunk/reactos/ntoskrnl/ntoskrnl.xml

Modified: trunk/reactos/include/ndk/rtlfuncs.h
--- trunk/reactos/include/ndk/rtlfuncs.h	2005-09-08 04:27:02 UTC (rev 17733)
+++ trunk/reactos/include/ndk/rtlfuncs.h	2005-09-08 05:03:34 UTC (rev 17734)
@@ -11,6 +11,8 @@
 
 /* DEPENDENCIES **************************************************************/
 #include <ntnls.h>
+#include "extypes.h"
+#include "rtltypes.h"
 
 /* PROTOTYPES ****************************************************************/
 

Modified: trunk/reactos/lib/ntdll/ntdll.xml
--- trunk/reactos/lib/ntdll/ntdll.xml	2005-09-08 04:27:02 UTC (rev 17733)
+++ trunk/reactos/lib/ntdll/ntdll.xml	2005-09-08 05:03:34 UTC (rev 17734)
@@ -42,27 +42,6 @@
 		<file>sscanf.c</file>
 		<file>swprintf.c</file>
 	</directory>
-	<directory name="stdlib">
-		<file>abs.c</file>
-		<file>atoi64.c</file>
-		<file>atoi.c</file>
-		<file>atol.c</file>
-		<file>bsearch.c</file>
-		<file>itoa.c</file>
-		<file>itow.c</file>
-		<file>labs.c</file>
-		<file>lfind.c</file>
-		<file>mbstowcs.c</file>
-		<file>splitp.c</file>
-		<file>strtol.c</file>
-		<file>strtoul.c</file>
-		<file>wcstol.c</file>
-		<file>wcstombs.c</file>
-		<file>wcstoul.c</file>
-		<file>wtoi64.c</file>
-		<file>wtoi.c</file>
-		<file>wtol.c</file>
-	</directory>
 	<directory name="def">
 		<file>ntdll.rc</file>
 	</directory>

Added: trunk/reactos/lib/string/abs.c
--- trunk/reactos/lib/string/abs.c	2005-09-08 04:27:02 UTC (rev 17733)
+++ trunk/reactos/lib/string/abs.c	2005-09-08 05:03:34 UTC (rev 17734)
@@ -0,0 +1,10 @@
+#include <string.h>
+
+/*
+ * @implemented
+ */
+int
+abs(int j)
+{
+  return j<0 ? -j : j;
+}

Added: trunk/reactos/lib/string/atoi.c
--- trunk/reactos/lib/string/atoi.c	2005-09-08 04:27:02 UTC (rev 17733)
+++ trunk/reactos/lib/string/atoi.c	2005-09-08 05:03:34 UTC (rev 17734)
@@ -0,0 +1,11 @@
+#include <string.h>
+#include <stdlib.h>
+
+/*
+ * @implemented
+ */
+int
+atoi(const char *str)
+{
+  return (int)strtol(str, 0, 10);
+}

Added: trunk/reactos/lib/string/atoi64.c
--- trunk/reactos/lib/string/atoi64.c	2005-09-08 04:27:02 UTC (rev 17733)
+++ trunk/reactos/lib/string/atoi64.c	2005-09-08 05:03:34 UTC (rev 17734)
@@ -0,0 +1,36 @@
+#include <string.h>
+#include <ctype.h>
+
+/*
+ * @implemented
+ */
+__int64
+_atoi64 (const char *nptr)
+{
+   int c;
+   __int64 value;
+   int sign;
+
+   while (isspace((int)*nptr))
+        ++nptr;
+
+   c = (int)*nptr++;
+   sign = c;
+   if (c == '-' || c == '+')
+        c = (int)*nptr++;
+
+   value = 0;
+
+   while (isdigit(c))
+     {
+        value = 10 * value + (c - '0');
+        c = (int)*nptr++;
+     }
+
+   if (sign == '-')
+       return -value;
+   else
+       return value;
+}
+
+/* EOF */

Added: trunk/reactos/lib/string/atol.c
--- trunk/reactos/lib/string/atol.c	2005-09-08 04:27:02 UTC (rev 17733)
+++ trunk/reactos/lib/string/atol.c	2005-09-08 05:03:34 UTC (rev 17734)
@@ -0,0 +1,11 @@
+#include <string.h>
+#include <stdlib.h>
+
+/*
+ * @implemented
+ */
+long
+atol(const char *str)
+{
+  return strtol(str, 0, 10);
+}

Added: trunk/reactos/lib/string/bsearch.c
--- trunk/reactos/lib/string/bsearch.c	2005-09-08 04:27:02 UTC (rev 17733)
+++ trunk/reactos/lib/string/bsearch.c	2005-09-08 05:03:34 UTC (rev 17734)
@@ -0,0 +1,27 @@
+#include <string.h>
+
+/*
+ * @implemented
+ */
+void *
+bsearch(const void *key, const void *base0, size_t nelem,
+	size_t size, int (*cmp)(const void *ck, const void *ce))
+{
+  char *base = (char *)base0;
+  int lim, cmpval;
+  void *p;
+
+  for (lim = nelem; lim != 0; lim >>= 1)
+  {
+    p = base + (lim >> 1) * size;
+    cmpval = (*cmp)(key, p);
+    if (cmpval == 0)
+      return p;
+    if (cmpval > 0)
+    {				/* key > p: move right */
+      base = (char *)p + size;
+      lim--;
+    } /* else move left */
+  }
+  return 0;
+}

Added: trunk/reactos/lib/string/itoa.c
--- trunk/reactos/lib/string/itoa.c	2005-09-08 04:27:02 UTC (rev 17733)
+++ trunk/reactos/lib/string/itoa.c	2005-09-08 05:03:34 UTC (rev 17734)
@@ -0,0 +1,167 @@
+#include <string.h>
+#include <stdlib.h>
+
+/*
+ * @implemented
+ */
+char *
+_i64toa(__int64 value, char *string, int radix)
+{
+  char tmp[65];
+  char *tp = tmp;
+  __int64 i;
+  unsigned __int64 v;
+  __int64 sign;
+  char *sp;
+
+  if (radix > 36 || radix <= 1)
+  {
+    return 0;
+  }
+
+  sign = (radix == 10 && value < 0);
+  if (sign)
+    v = -value;
+  else
+    v = (unsigned __int64)value;
+  while (v || tp == tmp)
+  {
+    i = v % radix;
+    v = v / radix;
+    if (i < 10)
+      *tp++ = i+'0';
+    else
+      *tp++ = i + 'a' - 10;
+  }
+
+  sp = string;
+  if (sign)
+    *sp++ = '-';
+  while (tp > tmp)
+    *sp++ = *--tp;
+  *sp = 0;
+  return string;
+}
+
+
+/*
+ * @implemented
+ */
+char *
+_ui64toa(unsigned __int64 value, char *string, int radix)
+{
+  char tmp[65];
+  char *tp = tmp;
+  __int64 i;
+  unsigned __int64 v;
+  char *sp;
+
+  if (radix > 36 || radix <= 1)
+  {
+    return 0;
+  }
+
+  v = (unsigned __int64)value;
+  while (v || tp == tmp)
+  {
+    i = v % radix;
+    v = v / radix;
+    if (i < 10)
+      *tp++ = i+'0';
+    else
+      *tp++ = i + 'a' - 10;
+  }
+
+  sp = string;
+  while (tp > tmp)
+    *sp++ = *--tp;
+  *sp = 0;
+  return string;
+}
+
+
+/*
+ * @implemented
+ */
+char *
+_itoa(int value, char *string, int radix)
+{
+  return _ltoa(value, string, radix);
+}
+
+
+/*
+ * @implemented
+ */
+char *
+_ltoa(long value, char *string, int radix)
+{
+    unsigned long val;
+    int negative;
+    char buffer[33];
+    char *pos;
+    int digit;
+
+    if (value < 0 && radix == 10) {
+	negative = 1;
+        val = -value;
+    } else {
+	negative = 0;
+        val = value;
+    } /* if */
+
+    pos = &buffer[32];
+    *pos = '\0';
+
+    do {
+	digit = val % radix;
+	val = val / radix;
+	if (digit < 10) {
+	    *--pos = '0' + digit;
+	} else {
+	    *--pos = 'a' + digit - 10;
+	} /* if */
+    } while (val != 0L);
+
+    if (negative) {
+	*--pos = '-';
+    } /* if */
+
+    memcpy(string, pos, &buffer[32] - pos + 1);
+    return string;
+}
+
+
+/*
+ * @implemented
+ */
+char *
+_ultoa(unsigned long value, char *string, int radix)
+{
+  char tmp[33];
+  char *tp = tmp;
+  long i;
+  unsigned long v = value;
+  char *sp;
+
+  if (radix > 36 || radix <= 1)
+  {
+    return 0;
+  }
+
+  while (v || tp == tmp)
+  {
+    i = v % radix;
+    v = v / radix;
+    if (i < 10)
+      *tp++ = i+'0';
+    else
+      *tp++ = i + 'a' - 10;
+  }
+
+  sp = string;
+  while (tp > tmp)
+    *sp++ = *--tp;
+  *sp = 0;
+  return string;
+}

Added: trunk/reactos/lib/string/itow.c
--- trunk/reactos/lib/string/itow.c	2005-09-08 04:27:02 UTC (rev 17733)
+++ trunk/reactos/lib/string/itow.c	2005-09-08 05:03:34 UTC (rev 17734)
@@ -0,0 +1,200 @@
+#include <string.h>
+
+/*
+ * @implemented
+ */
+wchar_t *
+_i64tow(__int64 value, wchar_t *string, int radix)
+{
+  wchar_t tmp[65];
+  wchar_t *tp = tmp;
+  __int64 i;
+  unsigned __int64 v;
+  __int64 sign;
+  wchar_t *sp;
+
+  if (radix > 36 || radix <= 1)
+  {
+    return 0;
+  }
+
+  sign = (radix == 10 && value < 0);
+  if (sign)
+    v = -value;
+  else
+    v = (unsigned __int64)value;
+  while (v || tp == tmp)
+  {
+    i = v % radix;
+    v = v / radix;
+    if (i < 10)
+      *tp++ = i+L'0';
+    else
+      *tp++ = i + L'a' - 10;
+  }
+
+  sp = string;
+  if (sign)
+    *sp++ = L'-';
+  while (tp > tmp)
+    *sp++ = *--tp;
+  *sp = 0;
+  return string;
+}
+
+
+/*
+ * @implemented
+ */
+wchar_t *
+_ui64tow(unsigned __int64 value, wchar_t *string, int radix)
+{
+  wchar_t tmp[65];
+  wchar_t *tp = tmp;
+  __int64 i;
+  unsigned __int64 v;
+  wchar_t *sp;
+
+  if (radix > 36 || radix <= 1)
+  {
+    return 0;
+  }
+
+  v = (unsigned __int64)value;
+  while (v || tp == tmp)
+  {
+    i = v % radix;
+    v = v / radix;
+    if (i < 10)
+      *tp++ = i+L'0';
+    else
+      *tp++ = i + L'a' - 10;
+  }
+
+  sp = string;
+  while (tp > tmp)
+    *sp++ = *--tp;
+  *sp = 0;
+  return string;
+}
+
+
+/*
+ * @implemented
+ */
+wchar_t *
+_itow(int value, wchar_t *string, int radix)
+{
+  wchar_t tmp[33];
+  wchar_t *tp = tmp;
+  int i;
+  unsigned v;
+  int sign;
+  wchar_t *sp;
+
+  if (radix > 36 || radix <= 1)
+  {
+    return 0;
+  }
+
+  sign = (radix == 10 && value < 0);
+  if (sign)
+    v = -value;
+  else
+    v = (unsigned)value;
+  while (v || tp == tmp)
+  {
+    i = v % radix;
+    v = v / radix;
+    if (i < 10)
+      *tp++ = i+L'0';
+    else
+      *tp++ = i + L'a' - 10;
+  }
+
+  sp = string;
+  if (sign)
+    *sp++ = L'-';
+  while (tp > tmp)
+    *sp++ = *--tp;
+  *sp = 0;
+  return string;
+}
+
+
+/*
+ * @implemented
+ */
+wchar_t *
+_ltow(long value, wchar_t *string, int radix)
+{
+  wchar_t tmp[33];
+  wchar_t *tp = tmp;
+  long i;
+  unsigned long v;
+  int sign;
+  wchar_t *sp;
+
+  if (radix > 36 || radix <= 1)
+  {
+    return 0;
+  }
+
+  sign = (radix == 10 && value < 0);
+  if (sign)
+    v = -value;
+  else
+    v = (unsigned long)value;
+  while (v || tp == tmp)
+  {
+    i = v % radix;
+    v = v / radix;
+    if (i < 10)
+      *tp++ = i+L'0';
+    else
+      *tp++ = i + L'a' - 10;
+  }
+
+  sp = string;
+  if (sign)
+    *sp++ = L'-';
+  while (tp > tmp)
+    *sp++ = *--tp;
+  *sp = 0;
+  return string;
+}
+
+
+/*
+ * @implemented
+ */
+wchar_t *
+_ultow(unsigned long value, wchar_t *string, int radix)
+{
+  wchar_t tmp[33];
+  wchar_t *tp = tmp;
+  long i;
+  unsigned long v = value;
+  wchar_t *sp;
+
+  if (radix > 36 || radix <= 1)
+  {
+    return 0;
+  }
+
+  while (v || tp == tmp)
+  {
+    i = v % radix;
+    v = v / radix;
+    if (i < 10)
+      *tp++ = i+L'0';
+    else
+      *tp++ = i + L'a' - 10;
+  }
+
+  sp = string;
+  while (tp > tmp)
+    *sp++ = *--tp;
+  *sp = 0;
+  return string;
+}

Added: trunk/reactos/lib/string/labs.c
--- trunk/reactos/lib/string/labs.c	2005-09-08 04:27:02 UTC (rev 17733)
+++ trunk/reactos/lib/string/labs.c	2005-09-08 05:03:34 UTC (rev 17734)
@@ -0,0 +1,9 @@
+#include <string.h>
+/*
+ * @implemented
+ */
+long
+labs(long j)
+{
+  return j<0 ? -j : j;
+}

Added: trunk/reactos/lib/string/lfind.c
--- trunk/reactos/lib/string/lfind.c	2005-09-08 04:27:02 UTC (rev 17733)
+++ trunk/reactos/lib/string/lfind.c	2005-09-08 05:03:34 UTC (rev 17734)
@@ -0,0 +1,20 @@
+#include <string.h>
+/*
+ * @implemented
+ */
+void *_lfind(const void *key, const void *base, size_t *nelp,
+         size_t width, int (*compar)(const void *, const void *))
+{
+  char* char_base = (char*)base;
+  size_t i;
+
+  for (i = 0; i < *nelp; i++)
+    {
+      if (compar(key, char_base) == 0)
+	return char_base;
+
+      char_base += width;
+    }
+
+  return NULL;
+}

Added: trunk/reactos/lib/string/mbstowcs.c
--- trunk/reactos/lib/string/mbstowcs.c	2005-09-08 04:27:02 UTC (rev 17733)
+++ trunk/reactos/lib/string/mbstowcs.c	2005-09-08 05:03:34 UTC (rev 17734)
@@ -0,0 +1,61 @@
+#include <windows.h>
+#define NTOS_MODE_USER
+#define _NTSYSTEM_
+#include <ndk/umtypes.h>
+#include <ndk/rtlfuncs.h>
+#include <string.h>
+
+/*
+ * @implemented
+ */
+int mbtowc (wchar_t *wchar, const char *mbchar, size_t count)
+{
+	NTSTATUS Status;
+	ULONG Size;
+
+	if (wchar == NULL)
+		return 0;
+
+	Status = RtlMultiByteToUnicodeN (wchar,
+	                                 sizeof(WCHAR),
+	                                 &Size,
+	                                 (char *)mbchar,
+	                                 count);
+	if (!NT_SUCCESS(Status))
+		return -1;
+
+	return (int)Size;
+}
+
+/*
+ * @implemented
+ */
+size_t mbstowcs (wchar_t *wcstr, const char *mbstr, size_t count)
+{
+	NTSTATUS Status;
+	ULONG Size;
+	ULONG Length;
+
+	Length = strlen (mbstr);
+
+	if (wcstr == NULL)
+	{
+		RtlMultiByteToUnicodeSize (&Size,
+		                           (char *)mbstr,
+		                           Length);
+
+		return (size_t)Size;
+	}
+
+	Status = RtlMultiByteToUnicodeN (wcstr,
+	                                 count,
+	                                 &Size,
+	                                 (char *)mbstr,
+	                                 Length);
+	if (!NT_SUCCESS(Status))
+		return -1;
+
+	return (size_t)Size;
+}
+
+/* EOF */

Added: trunk/reactos/lib/string/rand.c
--- trunk/reactos/lib/string/rand.c	2005-09-08 04:27:02 UTC (rev 17733)
+++ trunk/reactos/lib/string/rand.c	2005-09-08 05:03:34 UTC (rev 17734)
@@ -0,0 +1,29 @@
+#include <stdlib.h>
+
+#if defined(__GNUC__)
+static unsigned long long next = 0;
+#else
+static unsigned __int64 next = 0;
+#endif
+
+/*
+ * @implemented
+ */
+int rand(void)
+{
+#if defined(__GNUC__)
+	next = next * 0x5deece66dLL + 11;
+#else
+	next = next * 0x5deece66di64 + 11;
+#endif
+	return (int)((next >> 16) & RAND_MAX);
+}
+
+
+/*
+ * @implemented
+ */
+void srand(unsigned seed)
+{
+	next = seed;
+}

Added: trunk/reactos/lib/string/splitp.c
--- trunk/reactos/lib/string/splitp.c	2005-09-08 04:27:02 UTC (rev 17733)
+++ trunk/reactos/lib/string/splitp.c	2005-09-08 05:03:34 UTC (rev 17734)
@@ -0,0 +1,50 @@
+#include <string.h>
+/*
+ * @implemented
+ */
+void _splitpath(const char* path, char* drive, char* dir, char* fname, char* ext)
+{
+    char* tmp_drive;
+    char* tmp_dir;
+    char* tmp_ext;
+
+    tmp_drive = (char*)strchr(path,':');
+    if (drive) {
+	if (tmp_drive) {
+	    strncpy(drive,tmp_drive-1,2);
+	    *(drive+2) = 0;
+	} else {
+	    *drive = 0;
+	}
+    }
+    if (!tmp_drive) {
+	tmp_drive = (char*)path - 1;
+    }
+
+    tmp_dir = (char*)strrchr(path,'\\');
+    if (dir) {
+	if (tmp_dir) {
+	    strncpy(dir,tmp_drive+1,tmp_dir-tmp_drive);
+            *(dir+(tmp_dir-tmp_drive)) = 0;
+	} else {
+	    *dir =0;
+	}
+    }
+
+    tmp_ext = (char*)strrchr(path,'.');
+    if (!tmp_ext) {
+	tmp_ext = (char*)path+strlen(path);
+    }
+    if (ext) {
+        strcpy(ext,tmp_ext);
+    }
+
+    if (tmp_dir) {
+        strncpy(fname,tmp_dir+1,tmp_ext-tmp_dir-1);
+        *(fname+(tmp_ext-tmp_dir-1)) = 0;
+    } else {
+        strncpy(fname,tmp_drive+1,tmp_ext-tmp_drive-1);
+        *(fname+(tmp_ext-path))=0;
+    }
+}
+

Modified: trunk/reactos/lib/string/string.xml
--- trunk/reactos/lib/string/string.xml	2005-09-08 04:27:02 UTC (rev 17733)
+++ trunk/reactos/lib/string/string.xml	2005-09-08 05:03:34 UTC (rev 17734)
@@ -76,4 +76,24 @@
 	<file>wstring.c</file>
 	<file>wcsrev.c</file>
 	<file>wcsnset.c</file>
+	<file>abs.c</file>
+	<file>atoi64.c</file>
+	<file>atoi.c</file>
+	<file>atol.c</file>
+	<file>bsearch.c</file>
+	<file>itoa.c</file>
+	<file>itow.c</file>
+	<file>labs.c</file>
+	<file>lfind.c</file>
+	<file>mbstowcs.c</file>
+	<file>splitp.c</file>
+	<file>strtol.c</file>
+	<file>strtoul.c</file>
+	<file>wcstol.c</file>
+	<file>wcstombs.c</file>
+	<file>wcstoul.c</file>
+	<file>wtoi64.c</file>
+	<file>wtoi.c</file>
+	<file>wtol.c</file>
+	<file>rand.c</file>
 </module>

Added: trunk/reactos/lib/string/strtol.c
--- trunk/reactos/lib/string/strtol.c	2005-09-08 04:27:02 UTC (rev 17733)
+++ trunk/reactos/lib/string/strtol.c	2005-09-08 05:03:34 UTC (rev 17734)
@@ -0,0 +1,90 @@
+#include <string.h>
+#include <limits.h>
+#include <ctype.h>
+
+/*
+ * @implemented
+ */
+long
+strtol(const char *nptr, char **endptr, int base)
+{
+  const char *s = nptr;
+  unsigned long acc;
+  int c;
+  unsigned long cutoff;
+  int neg = 0, 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.
+   */
+  do {
+    c = *s++;
+  } while (isspace(c));
+  if (c == '-')
+  {
+    neg = 1;
+    c = *s++;
+  }
+  else 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 longs is
+   * [-2147483648..2147483647] and the input base is 10,
+   * cutoff will be set to 214748364 and cutlim to either
+   * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated
+   * a value > 214748364, 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.
+   */
+  cutoff = neg ? -(unsigned long)LONG_MIN : LONG_MAX;
+  cutlim = cutoff % (unsigned long)base;
+  cutoff /= (unsigned long)base;
+  for (acc = 0, any = 0;; c = *s++)
+  {
+    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 *= base;
+      acc += c;
+    }
+  }
+  if (any < 0)
+  {
+    acc = neg ? LONG_MIN : LONG_MAX;
+  }
+  else if (neg)
+    acc = -acc;
+  if (endptr != 0)
+    *endptr = any ? (char *)s - 1 : (char *)nptr;
+  return acc;
+}

Added: trunk/reactos/lib/string/strtoul.c
--- trunk/reactos/lib/string/strtoul.c	2005-09-08 04:27:02 UTC (rev 17733)
+++ trunk/reactos/lib/string/strtoul.c	2005-09-08 05:03:34 UTC (rev 17734)
@@ -0,0 +1,73 @@
+#include <string.h>
+#include <limits.h>
+#include <ctype.h>
+
+/*
+ * Convert a string to an unsigned long integer.
+ *
+ * Ignores `locale' stuff.  Assumes that the upper and lower case
+ * alphabets and digits are each contiguous.
+ *
+ * @implemented
+ */
+unsigned long
+strtoul(const char *nptr, char **endptr, int base)
+{
+  const char *s = nptr;
+  unsigned long acc;
+  int c;
+  unsigned long cutoff;
+  int neg = 0, any, cutlim;
+
+  /*
+   * See strtol for comments as to the logic used.
+   */
+  do {
+    c = *s++;
+  } while (isspace(c));
+  if (c == '-')
+  {
+    neg = 1;
+    c = *s++;
+  }
+  else 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;
+  cutoff = (unsigned long)ULONG_MAX / (unsigned long)base;
+  cutlim = (unsigned long)ULONG_MAX % (unsigned long)base;
+  for (acc = 0, any = 0;; c = *s++)
+  {
+    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 *= base;
+      acc += c;
+    }
+  }
+  if (any < 0)
+  {
+    acc = ULONG_MAX;
+  }
+  else if (neg)
+    acc = -acc;
+  if (endptr != 0)
+    *endptr = any ? (char *)s - 1 : (char *)nptr;
+  return acc;
+}

Added: trunk/reactos/lib/string/wcstol.c
--- trunk/reactos/lib/string/wcstol.c	2005-09-08 04:27:02 UTC (rev 17733)
+++ trunk/reactos/lib/string/wcstol.c	2005-09-08 05:03:34 UTC (rev 17734)
@@ -0,0 +1,90 @@
+#include <string.h>
+#include <ctype.h>
+#include <limits.h>
+
+/*
+ * @implemented
+ */
+long
+wcstol(const wchar_t *nptr, wchar_t **endptr, int base)
+{
+  const wchar_t *s = nptr;
+  unsigned long acc;
+  int c;
+  unsigned long cutoff;
+  int neg = 0, 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.
+   */
+  do {
+    c = *s++;
+  } while (iswctype(c, _SPACE));
+  if (c == '-')
+  {
+    neg = 1;
+    c = *s++;
+  }
+  else if (c == L'+')
+    c = *s++;
+  if ((base == 0 || base == 16) &&
+      c == L'0' && (*s == L'x' || *s == L'X'))
+  {
+    c = s[1];
+    s += 2;
+    base = 16;
+  }
+  if (base == 0)
+    base = c == L'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 longs is
+   * [-2147483648..2147483647] and the input base is 10,
+   * cutoff will be set to 214748364 and cutlim to either
+   * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated
+   * a value > 214748364, 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.
[truncated at 1000 lines; 263 more skipped]