Started modularising vg_mylibc.  Put all the standalone stuff -- ie. not
relying on any other modules -- in m_libcbase.

Also converted the 'size' parameters to functions like VG_(memcpy) and
VG_(strncpy) from Int to SizeT, as they should be.

Also removed VG_(atoll16) and VG_(toupper), which weren't being used.

Also made VG_(atoll36) less flexible -- it now only does base-36 numbers
instead of any base in the range 2..36, since base-36 is the only one we
need.  As part of that, I fixed a horrible bug in it which caused it to
return incorrect answers for any number containing the digits 'A'..'I'!
(Eg. for "A; it would return 17 instead of 10!)

Had to disable the assertions in VG_(string_match), since this module can't
see vg_assert, which wasn't ideal but also isn't a disaster.


git-svn-id: svn://svn.valgrind.org/valgrind/trunk@3838 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/coregrind/vg_mylibc.c b/coregrind/vg_mylibc.c
index c6678ed..989bcd3 100644
--- a/coregrind/vg_mylibc.c
+++ b/coregrind/vg_mylibc.c
@@ -33,6 +33,7 @@
 #include "core.h"
 #include "pub_core_aspacemgr.h"
 #include "pub_core_debuglog.h"    /* VG_(debugLog_vprintf) */
+#include "pub_core_libcbase.h"
 #include "pub_core_main.h"
 #include "pub_core_options.h"
 #include "pub_core_stacktrace.h"
@@ -508,334 +509,10 @@
    return ret;
 }
 
-
 /* ---------------------------------------------------------------------
-   Misc str* functions.
+   strdup()
    ------------------------------------------------------------------ */
 
-Bool VG_(isspace) ( Char c )
-{
-   return (c == ' '  || c == '\n' || c == '\t' || 
-           c == '\f' || c == '\v' || c == '\r');
-}
-
-Bool VG_(isdigit) ( Char c )
-{
-   return (c >= '0' && c <= '9');
-}
-
-Int VG_(strlen) ( const Char* str )
-{
-   Int i = 0;
-   while (str[i] != 0) i++;
-   return i;
-}
-
-
-Long VG_(atoll) ( Char* str )
-{
-   Bool neg = False;
-   Long n = 0;
-   if (*str == '-') { str++; neg = True; };
-   while (*str >= '0' && *str <= '9') {
-      n = 10*n + (Long)(*str - '0');
-      str++;
-   }
-   if (neg) n = -n;
-   return n;
-}
-
-
-Long VG_(atoll16) ( Char* str )
-{
-   Bool neg = False;
-   Long n = 0;
-   if (*str == '-') { str++; neg = True; };
-   while (True) {
-      if (*str >= '0' && *str <= '9') {
-         n = 16*n + (Long)(*str - '0');
-      }
-      else 
-      if (*str >= 'A' && *str <= 'F') {
-         n = 16*n + (Long)((*str - 'A') + 10);
-      }
-      else 
-      if (*str >= 'a' && *str <= 'f') {
-         n = 16*n + (Long)((*str - 'a') + 10);
-      }
-      else {
-	break;
-      }
-      str++;
-   }
-   if (neg) n = -n;
-   return n;
-}
-
-Long VG_(atoll36) ( UInt base, Char* str )
-{
-   Bool neg = False;
-   Long n = 0;
-   vg_assert(base >= 2 && base <= 36);
-   if (*str == '-') { str++; neg = True; };
-   while (True) {
-      if (*str >= '0' 
-          && *str <= (Char)('9' - (10 - base))) {
-         n = base*n + (Long)(*str - '0');
-      }
-      else 
-      if (base > 10 && *str >= 'A' 
-          && *str <= (Char)('Z' - (36 - base))) {
-         n = base*n + (Long)((*str - 'A') + 10);
-      }
-      else 
-      if (base > 10 && *str >= 'a' 
-          && *str <= (Char)('z' - (36 - base))) {
-         n = base*n + (Long)((*str - 'a') + 10);
-      }
-      else {
-	break;
-      }
-      str++;
-   }
-   if (neg) n = -n;
-   return n;
-}
-
-
-Char* VG_(strcat) ( Char* dest, const Char* src )
-{
-   Char* dest_orig = dest;
-   while (*dest) dest++;
-   while (*src) *dest++ = *src++;
-   *dest = 0;
-   return dest_orig;
-}
-
-
-Char* VG_(strncat) ( Char* dest, const Char* src, Int n )
-{
-   Char* dest_orig = dest;
-   while (*dest) dest++;
-   while (*src && n > 0) { *dest++ = *src++; n--; }
-   *dest = 0;
-   return dest_orig;
-}
-
-
-Char* VG_(strpbrk) ( const Char* s, const Char* accept )
-{
-   const Char* a;
-   while (*s) {
-      a = accept;
-      while (*a)
-         if (*a++ == *s)
-            return (Char *) s;
-      s++;
-   }
-   return NULL;
-}
-
-
-Char* VG_(strcpy) ( Char* dest, const Char* src )
-{
-   Char* dest_orig = dest;
-   while (*src) *dest++ = *src++;
-   *dest = 0;
-   return dest_orig;
-}
-
-
-/* Copy bytes, not overrunning the end of dest and always ensuring
-   zero termination. */
-void VG_(strncpy_safely) ( Char* dest, const Char* src, Int ndest )
-{
-   Int i;
-   vg_assert(ndest > 0);
-   i = 0;
-   while (True) {
-      dest[i] = 0;
-      if (src[i] == 0) return;
-      if (i >= ndest-1) return;
-      dest[i] = src[i];
-      i++;
-   }
-}
-
-
-Char* VG_(strncpy) ( Char* dest, const Char* src, Int ndest )
-{
-   Int i = 0;
-   while (True) {
-      if (i >= ndest) return dest;     /* reached limit */
-      dest[i] = src[i];
-      if (src[i++] == 0) {
-         /* reached NUL;  pad rest with zeroes as required */
-         while (i < ndest) dest[i++] = 0;
-         return dest;
-      }
-   }
-}
-
-
-Int VG_(strcmp) ( const Char* s1, const Char* s2 )
-{
-   while (True) {
-      if (*s1 == 0 && *s2 == 0) return 0;
-      if (*s1 == 0) return -1;
-      if (*s2 == 0) return 1;
-
-      if (*(UChar*)s1 < *(UChar*)s2) return -1;
-      if (*(UChar*)s1 > *(UChar*)s2) return 1;
-
-      s1++; s2++;
-   }
-}
-
-static Bool isterm ( Char c )
-{
-   return ( VG_(isspace)(c) || 0 == c );
-}
-
-
-Int VG_(strcmp_ws) ( const Char* s1, const Char* s2 )
-{
-   while (True) {
-      if (isterm(*s1) && isterm(*s2)) return 0;
-      if (isterm(*s1)) return -1;
-      if (isterm(*s2)) return 1;
-
-      if (*(UChar*)s1 < *(UChar*)s2) return -1;
-      if (*(UChar*)s1 > *(UChar*)s2) return 1;
-
-      s1++; s2++;
-   }
-}
-
-
-Int VG_(strncmp) ( const Char* s1, const Char* s2, Int nmax )
-{
-   Int n = 0;
-   while (True) {
-      if (n >= nmax) return 0;
-      if (*s1 == 0 && *s2 == 0) return 0;
-      if (*s1 == 0) return -1;
-      if (*s2 == 0) return 1;
-
-      if (*(UChar*)s1 < *(UChar*)s2) return -1;
-      if (*(UChar*)s1 > *(UChar*)s2) return 1;
-
-      s1++; s2++; n++;
-   }
-}
-
-
-Int VG_(strncmp_ws) ( const Char* s1, const Char* s2, Int nmax )
-{
-   Int n = 0;
-   while (True) {
-      if (n >= nmax) return 0;
-      if (isterm(*s1) && isterm(*s2)) return 0;
-      if (isterm(*s1)) return -1;
-      if (isterm(*s2)) return 1;
-
-      if (*(UChar*)s1 < *(UChar*)s2) return -1;
-      if (*(UChar*)s1 > *(UChar*)s2) return 1;
-
-      s1++; s2++; n++;
-   }
-}
-
-
-Char* VG_(strstr) ( const Char* haystack, Char* needle )
-{
-   Int n; 
-   if (haystack == NULL)
-      return NULL;
-   n = VG_(strlen)(needle);
-   while (True) {
-      if (haystack[0] == 0) 
-         return NULL;
-      if (VG_(strncmp)(haystack, needle, n) == 0) 
-         return (Char*)haystack;
-      haystack++;
-   }
-}
-
-
-Char* VG_(strchr) ( const Char* s, Char c )
-{
-   while (True) {
-      if (*s == c) return (Char*)s;
-      if (*s == 0) return NULL;
-      s++;
-   }
-}
-
-
-Char* VG_(strrchr) ( const Char* s, Char c )
-{
-   Int n = VG_(strlen)(s);
-   while (--n > 0) {
-      if (s[n] == c) return (Char*)s + n;
-   }
-   return NULL;
-}
-
-
-void* VG_(memcpy) ( void *dest, const void *src, Int sz )
-{
-   const Char *s = (const Char *)src;
-   Char *d = (Char *)dest;
-   vg_assert(sz >= 0);
-
-   while (sz--)
-      *d++ = *s++;
-
-   return dest;
-}
-
-
-void* VG_(memset) ( void *dest, Int c, Int sz )
-{
-   Char *d = (Char *)dest;
-   vg_assert(sz >= 0);
-
-   while (sz--)
-      *d++ = c;
-
-   return dest;
-}
-
-Int VG_(memcmp) ( const void* s1, const void* s2, Int n )
-{
-   Int res;
-   UChar a0;
-   UChar b0;
-   vg_assert(n >= 0);
-
-   while (n != 0) {
-      a0 = ((UChar *) s1)[0];
-      b0 = ((UChar *) s2)[0];
-      s1 += 1;
-      s2 += 1;
-      res = a0 - b0;
-      if (res != 0)
-         return res;
-      n -= 1;
-   }
-   return 0;
-}
-
-Char VG_(toupper) ( Char c )
-{
-   if (c >= 'a' && c <= 'z')
-      return c + ('A' - 'a'); 
-   else
-      return c;
-}
-
-
 /* Inline just for the wrapper VG_(strdup) below */
 __inline__ Char* VG_(arena_strdup) ( ArenaId aid, const Char* s )
 {
@@ -861,67 +538,6 @@
 }
 
 /* ---------------------------------------------------------------------
-   A simple string matching routine, purloined from Hugs98.
-      '*'    matches any sequence of zero or more characters
-      '?'    matches any single character exactly 
-      '\c'   matches the character c only (ignoring special chars)
-      c      matches the character c only
-   ------------------------------------------------------------------ */
-
-/* Keep track of recursion depth. */
-static Int recDepth;
-
-static Bool string_match_wrk ( const Char* pat, const Char* str )
-{
-   vg_assert(recDepth >= 0 && recDepth < 500);
-   recDepth++;
-   for (;;) {
-      switch (*pat) {
-         case '\0' : recDepth--;
-                     return (*str=='\0');
-         case '*'  : do {
-                        if (string_match_wrk(pat+1,str)) {
-                           recDepth--;
-                           return True;
-                        }
-                     } while (*str++);
-                     recDepth--;
-                     return False;
-         case '?'  : if (*str++=='\0') {
-                        recDepth--;
-                        return False;
-                     }
-                     pat++;
-                     break;
-         case '\\' : if (*++pat == '\0') {
-                        recDepth--;
-                        return False; /* spurious trailing \ in pattern */
-                     }
-                     /* falls through to ... */
-         default   : if (*pat++ != *str++) {
-                        recDepth--;
-                        return False;
-                     }
-                     break;
-      }
-   }
-}
-
-Bool VG_(string_match) ( const Char* pat, const Char* str )
-{
-   Bool b;
-   recDepth = 0;
-   b = string_match_wrk ( pat, str );
-   vg_assert(recDepth == 0);
-   /*
-   VG_(printf)("%s   %s   %s\n",
-	       b?"TRUE ":"FALSE", pat, str);
-   */
-   return b;
-}
-
-
-/* ---------------------------------------------------------------------
    Assertery.
    ------------------------------------------------------------------ */
 
@@ -1586,106 +1202,6 @@
 }
 
 /* ---------------------------------------------------------------------
-   Generally useful...
-   ------------------------------------------------------------------ */
-
-Int VG_(log2) ( Int x ) 
-{
-   Int i;
-   /* Any more than 32 and we overflow anyway... */
-   for (i = 0; i < 32; i++) {
-      if (1 << i == x) return i;
-   }
-   return -1;
-}
-
-
-// Generic shell sort.  Like stdlib.h's qsort().
-void VG_(ssort)( void* base, SizeT nmemb, SizeT size,
-                 Int (*compar)(void*, void*) )
-{
-   Int   incs[14] = { 1, 4, 13, 40, 121, 364, 1093, 3280,
-                      9841, 29524, 88573, 265720,
-                      797161, 2391484 };
-   Int   lo = 0;
-   Int   hi = nmemb-1;
-   Int   i, j, h, bigN, hp;
-
-   bigN = hi - lo + 1; if (bigN < 2) return;
-   hp = 0; while (hp < 14 && incs[hp] < bigN) hp++; hp--;
-   vg_assert(0 <= hp && hp < 14);
-
-   #define SORT \
-   for ( ; hp >= 0; hp--) { \
-      h = incs[hp]; \
-      for (i = lo + h; i <= hi; i++) { \
-         ASSIGN(v,0, a,i); \
-         j = i; \
-         while (COMPAR(a,(j-h), v,0) > 0) { \
-            ASSIGN(a,j, a,(j-h)); \
-            j = j - h; \
-            if (j <= (lo + h - 1)) break; \
-         } \
-         ASSIGN(a,j, v,0); \
-      } \
-   }
-
-   // Specialised cases
-   if (sizeof(ULong) == size) {
-
-      #define ASSIGN(dst, dsti, src, srci) \
-      (dst)[(dsti)] = (src)[(srci)];      
-      
-      #define COMPAR(dst, dsti, src, srci) \
-      compar( (void*)(& (dst)[(dsti)]), (void*)(& (src)[(srci)]) )
-
-      ULong* a = (ULong*)base;
-      ULong  v[1];
-
-      SORT;
-
-   } else if (sizeof(UInt) == size) {
-
-      UInt* a = (UInt*)base;
-      UInt  v[1];
-
-      SORT;
-
-   } else if (sizeof(UShort) == size) {
-      UShort* a = (UShort*)base;
-      UShort  v[1];
-
-      SORT;
-
-   } else if (sizeof(UChar) == size) {
-      UChar* a = (UChar*)base;
-      UChar  v[1];
-
-      SORT;
-
-      #undef ASSIGN
-      #undef COMPAR
-
-   // General case
-   } else {
-      char* a = base;
-      char  v[size];      // will be at least 'size' bytes
-
-      #define ASSIGN(dst, dsti, src, srci) \
-      VG_(memcpy)( &dst[size*(dsti)], &src[size*(srci)], size );
-
-      #define COMPAR(dst, dsti, src, srci) \
-      compar( &dst[size*(dsti)], &src[size*(srci)] )
-
-      SORT;
-
-      #undef ASSIGN
-      #undef COMPAR
-   }
-   #undef SORT
-}
-
-/* ---------------------------------------------------------------------
    Gruesome hackery for connecting to a logging server over the network.
    This is all very Linux-kernel specific.
    ------------------------------------------------------------------ */