2 /*--------------------------------------------------------------------*/
3 /*--- Entirely standalone libc stuff. m_libcbase.c ---*/
4 /*--------------------------------------------------------------------*/
7 This file is part of Valgrind, a dynamic binary instrumentation
10 Copyright (C) 2000-2012 Julian Seward
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
28 The GNU General Public License is contained in the file COPYING.
31 #include "pub_core_basics.h"
32 #include "pub_core_libcbase.h"
34 /* ---------------------------------------------------------------------
36 ------------------------------------------------------------------ */
38 Bool VG_(isspace) ( Char c )
40 return (c == ' ' || c == '\n' || c == '\t' ||
41 c == '\f' || c == '\v' || c == '\r');
44 Bool VG_(isdigit) ( Char c )
46 return (c >= '0' && c <= '9');
49 /* ---------------------------------------------------------------------
50 Converting strings to numbers
51 ------------------------------------------------------------------ */
53 static Bool is_dec_digit(Char c, Long* digit)
55 if (c >= '0' && c <= '9') { *digit = (Long)(c - '0'); return True; }
59 static Bool is_hex_digit(Char c, Long* digit)
61 if (c >= '0' && c <= '9') { *digit = (Long)(c - '0'); return True; }
62 if (c >= 'A' && c <= 'F') { *digit = (Long)((c - 'A') + 10); return True; }
63 if (c >= 'a' && c <= 'f') { *digit = (Long)((c - 'a') + 10); return True; }
67 Long VG_(strtoll10) ( Char* str, Char** endptr )
69 Bool neg = False, converted = False;
70 Long n = 0, digit = 0;
73 // Skip leading whitespace.
74 while (VG_(isspace)(*str)) str++;
76 // Allow a leading '-' or '+'.
77 if (*str == '-') { str++; neg = True; }
78 else if (*str == '+') { str++; }
80 while (is_dec_digit(*str, &digit)) {
81 converted = True; // Ok, we've actually converted a digit.
86 if (!converted) str = str0; // If nothing converted, endptr points to
87 if (neg) n = -n; // the start of the string.
88 if (endptr) *endptr = str; // Record first failing character.
92 ULong VG_(strtoull10) ( Char* str, Char** endptr )
94 Bool converted = False;
99 // Skip leading whitespace.
100 while (VG_(isspace)(*str)) str++;
102 // Allow a leading '+'.
103 if (*str == '+') { str++; }
105 while (is_dec_digit(*str, &digit)) {
106 converted = True; // Ok, we've actually converted a digit.
111 if (!converted) str = str0; // If nothing converted, endptr points to
112 // the start of the string.
113 if (endptr) *endptr = str; // Record first failing character.
117 Long VG_(strtoll16) ( Char* str, Char** endptr )
119 Bool neg = False, converted = False;
120 Long n = 0, digit = 0;
123 // Skip leading whitespace.
124 while (VG_(isspace)(*str)) str++;
126 // Allow a leading '-' or '+'.
127 if (*str == '-') { str++; neg = True; }
128 else if (*str == '+') { str++; }
130 // Allow leading "0x", but only if there's a hex digit
133 && (*(str+1) == 'x' || *(str+1) == 'X')
134 && is_hex_digit( *(str+2), &digit )) {
138 while (is_hex_digit(*str, &digit)) {
139 converted = True; // Ok, we've actually converted a digit.
144 if (!converted) str = str0; // If nothing converted, endptr points to
145 if (neg) n = -n; // the start of the string.
146 if (endptr) *endptr = str; // Record first failing character.
150 ULong VG_(strtoull16) ( Char* str, Char** endptr )
152 Bool converted = False;
157 // Skip leading whitespace.
158 while (VG_(isspace)(*str)) str++;
160 // Allow a leading '+'.
161 if (*str == '+') { str++; }
163 // Allow leading "0x", but only if there's a hex digit
166 && (*(str+1) == 'x' || *(str+1) == 'X')
167 && is_hex_digit( *(str+2), &digit )) {
171 while (is_hex_digit(*str, &digit)) {
172 converted = True; // Ok, we've actually converted a digit.
177 if (!converted) str = str0; // If nothing converted, endptr points to
178 // the start of the string.
179 if (endptr) *endptr = str; // Record first failing character.
183 double VG_(strtod) ( Char* str, Char** endptr )
187 double n = 0, frac = 0, x = 0.1;
189 // Skip leading whitespace.
190 while (VG_(isspace)(*str)) str++;
192 // Allow a leading '-' or '+'.
193 if (*str == '-') { str++; neg = True; }
194 else if (*str == '+') { str++; }
196 while (is_dec_digit(*str, &digit)) {
203 while (is_dec_digit(*str, &digit)) {
212 if (endptr) *endptr = str; // Record first failing character.
216 Char VG_(tolower) ( Char c )
218 if ( c >= 'A' && c <= 'Z' ) {
219 return c - 'A' + 'a';
225 /* ---------------------------------------------------------------------
227 ------------------------------------------------------------------ */
229 SizeT VG_(strlen) ( const Char* str )
232 while (str[i] != 0) i++;
236 Char* VG_(strcat) ( Char* dest, const Char* src )
238 Char* dest_orig = dest;
239 while (*dest) dest++;
240 while (*src) *dest++ = *src++;
245 Char* VG_(strncat) ( Char* dest, const Char* src, SizeT n )
247 Char* dest_orig = dest;
248 while (*dest) dest++;
249 while (*src && n > 0) { *dest++ = *src++; n--; }
254 Char* VG_(strpbrk) ( const Char* s, const Char* accpt )
267 Char* VG_(strcpy) ( Char* dest, const Char* src )
269 Char* dest_orig = dest;
270 while (*src) *dest++ = *src++;
275 /* Copy bytes, not overrunning the end of dest and always ensuring
277 void VG_(strncpy_safely) ( Char* dest, const Char* src, SizeT ndest )
282 if (src[i] == 0) return;
283 if (i >= ndest-1) return;
289 Char* VG_(strncpy) ( Char* dest, const Char* src, SizeT ndest )
293 if (i >= ndest) return dest; /* reached limit */
296 /* reached NUL; pad rest with zeroes as required */
297 while (i < ndest) dest[i++] = 0;
303 Int VG_(strcmp) ( const Char* s1, const Char* s2 )
306 if (*(UChar*)s1 < *(UChar*)s2) return -1;
307 if (*(UChar*)s1 > *(UChar*)s2) return 1;
310 if (*s1 == 0) return 0;
316 Int VG_(strcasecmp) ( const Char* s1, const Char* s2 )
319 UChar c1 = (UChar)VG_(tolower)(*s1);
320 UChar c2 = (UChar)VG_(tolower)(*s2);
321 if (c1 < c2) return -1;
322 if (c1 > c2) return 1;
325 if (c1 == 0) return 0;
331 Int VG_(strncmp) ( const Char* s1, const Char* s2, SizeT nmax )
335 if (n >= nmax) return 0;
336 if (*(UChar*)s1 < *(UChar*)s2) return -1;
337 if (*(UChar*)s1 > *(UChar*)s2) return 1;
340 if (*s1 == 0) return 0;
346 Int VG_(strncasecmp) ( const Char* s1, const Char* s2, SizeT nmax )
352 if (n >= nmax) return 0;
353 c1 = (UChar)VG_(tolower)(*s1);
354 c2 = (UChar)VG_(tolower)(*s2);
355 if (c1 < c2) return -1;
356 if (c1 > c2) return 1;
359 if (c1 == 0) return 0;
365 Char* VG_(strstr) ( const Char* haystack, const Char* needle )
368 if (haystack == NULL)
370 n = VG_(strlen)(needle);
372 if (haystack[0] == 0)
374 if (VG_(strncmp)(haystack, needle, n) == 0)
375 return (Char*)haystack;
380 Char* VG_(strcasestr) ( const Char* haystack, const Char* needle )
383 if (haystack == NULL)
385 n = VG_(strlen)(needle);
387 if (haystack[0] == 0)
389 if (VG_(strncasecmp)(haystack, needle, n) == 0)
390 return (Char*)haystack;
395 Char* VG_(strchr) ( const Char* s, Char c )
398 if (*s == c) return (Char*)s;
399 if (*s == 0) return NULL;
404 Char* VG_(strrchr) ( const Char* s, Char c )
406 Int n = VG_(strlen)(s);
408 if (s[n] == c) return (Char*)s + n;
413 /* (code copied from glib then updated to valgrind types) */
416 VG_(strtok) (Char *s, const Char *delim)
418 return VG_(strtok_r) (s, delim, &olds);
422 VG_(strtok_r) (Char* s, const Char* delim, Char** saveptr)
429 /* Scan leading delimiters. */
430 s += VG_(strspn (s, delim));
437 /* Find the end of the token. */
439 s = VG_(strpbrk (token, delim));
441 /* This token finishes the string. */
442 *saveptr = token + VG_(strlen) (token);
445 /* Terminate the token and make OLDS point past it. */
452 static Bool isHex ( UChar c )
454 return ((c >= '0' && c <= '9') ||
455 (c >= 'a' && c <= 'f') ||
456 (c >= 'A' && c <= 'F'));
459 static UInt fromHex ( UChar c )
461 if (c >= '0' && c <= '9')
462 return (UInt)c - (UInt)'0';
463 if (c >= 'a' && c <= 'f')
464 return 10 + (UInt)c - (UInt)'a';
465 if (c >= 'A' && c <= 'F')
466 return 10 + (UInt)c - (UInt)'A';
468 // ??? need to vg_assert(0);
472 Bool VG_(parse_Addr) ( UChar** ppc, Addr* result )
474 Int used, limit = 2 * sizeof(Addr);
483 while (isHex(**ppc)) {
484 // ??? need to vg_assert(d < fromHex(**ppc));
485 *result = ((*result) << 4) | fromHex(**ppc);
488 if (used > limit) return False;
495 SizeT VG_(strspn) ( const Char* s, const Char* accpt )
499 for (p = s; *p != '\0'; ++p) {
500 for (a = accpt; *a != '\0'; ++a)
511 SizeT VG_(strcspn) ( const Char* s, const Char* reject )
515 if (VG_(strchr) (reject, *s++) == NULL)
524 /* ---------------------------------------------------------------------
526 ------------------------------------------------------------------ */
528 void* VG_(memcpy) ( void *dest, const void *src, SizeT sz )
530 const UChar* s = (const UChar*)src;
531 UChar* d = (UChar*)dest;
532 const UInt* sI = (const UInt*)src;
533 UInt* dI = (UInt*)dest;
535 if (VG_IS_4_ALIGNED(dI) && VG_IS_4_ALIGNED(sI)) {
555 s = (const UChar*)sI;
565 void* VG_(memmove)(void *dest, const void *src, SizeT sz)
571 for (i = 0; i < sz; i++) {
572 ((UChar*)dest)[i] = ((UChar*)src)[i];
575 else if (dest > src) {
576 for (i = 0; i < sz; i++) {
577 ((UChar*)dest)[sz-i-1] = ((UChar*)src)[sz-i-1];
583 void* VG_(memset) ( void *destV, Int c, SizeT sz )
586 Char* d = (Char*)destV;
587 while ((!VG_IS_4_ALIGNED(d)) && sz >= 1) {
618 Int VG_(memcmp) ( const void* s1, const void* s2, SizeT n )
621 const UChar *p1 = s1;
622 const UChar *p2 = s2;
639 /* ---------------------------------------------------------------------
640 Misc useful functions
641 ------------------------------------------------------------------ */
643 /////////////////////////////////////////////////////////////
644 /////////////////////////////////////////////////////////////
645 /// begin Bentley-McIlroy style quicksort
646 /// See "Engineering a Sort Function". Jon L Bentley, M. Douglas
647 /// McIlroy. Software Practice and Experience Vol 23(11), Nov 1993.
649 #define BM_MIN(a, b) \
652 #define BM_SWAPINIT(a, es) \
653 swaptype = ((a-(Char*)0) | es) % sizeof(Word) ? 2 \
654 : es > (SizeT)sizeof(Word) ? 1 \
657 #define BM_EXCH(a, b, t) \
658 (t = a, a = b, b = t)
660 #define BM_SWAP(a, b) \
662 ? bm_swapfunc(a, b, es, swaptype) \
663 : (void)BM_EXCH(*(Word*)(a), *(Word*)(b), t)
665 #define BM_VECSWAP(a, b, n) \
666 if (n > 0) bm_swapfunc(a, b, n, swaptype)
668 #define BM_PVINIT(pv, pm) \
670 pv = a, BM_SWAP(pv, pm); \
672 pv = (Char*)&v, v = *(Word*)pm
674 static Char* bm_med3 ( Char* a, Char* b, Char* c,
675 Int (*cmp)(void*,void*) ) {
677 ? (cmp(b, c) < 0 ? b : cmp(a, c) < 0 ? c : a)
678 : (cmp(b, c) > 0 ? b : cmp(a, c) > 0 ? c : a);
681 static void bm_swapfunc ( Char* a, Char* b, SizeT n, Int swaptype )
685 for ( ; n > 0; a += sizeof(Word), b += sizeof(Word),
687 BM_EXCH(*(Word*)a, *(Word*)b, t);
690 for ( ; n > 0; a += 1, b += 1, n -= 1)
695 static void bm_qsort ( Char* a, SizeT n, SizeT es,
696 Int (*cmp)(void*,void*) )
698 Char *pa, *pb, *pc, *pd, *pl, *pm, *pn, *pv;
705 for (pm = a + es; pm < a + n*es; pm += es)
706 for (pl = pm; pl > a && cmp(pl-es, pl) > 0; pl -= es)
716 pl = bm_med3(pl, pl+s, pl+2*s, cmp);
717 pm = bm_med3(pm-s, pm, pm+s, cmp);
718 pn = bm_med3(pn-2*s, pn-s, pn, cmp);
720 pm = bm_med3(pl, pm, pn, cmp);
724 pc = pd = a + (n-1)*es;
726 while (pb <= pc && (r = cmp(pb, pv)) <= 0) {
727 if (r == 0) { BM_SWAP(pa, pb); pa += es; }
730 while (pc >= pb && (r = cmp(pc, pv)) >= 0) {
731 if (r == 0) { BM_SWAP(pc, pd); pd -= es; }
740 s = BM_MIN(pa-a, pb-pa ); BM_VECSWAP(a, pb-s, s);
741 s = BM_MIN(pd-pc, pn-pd-es); BM_VECSWAP(pb, pn-s, s);
742 /* Now recurse. Do the smaller partition first with an explicit
743 recursion, then do the larger partition using a tail call.
744 Except we can't rely on gcc to implement a tail call in any sane
745 way, so simply jump back to the start. This guarantees stack
746 growth can never exceed O(log N) even in the worst case. */
751 bm_qsort(a, s1/es, es, cmp);
754 /* bm_qsort(pn-s2, s2/es, es, cmp); */
755 a = pn-s2; n = s2/es; es = es; cmp = cmp;
760 bm_qsort(pn-s2, s2/es, es, cmp);
763 /* bm_qsort(a, s1/es, es, cmp); */
764 a = a; n = s1/es; es = es; cmp = cmp;
777 /// end Bentley-McIlroy style quicksort
778 /////////////////////////////////////////////////////////////
779 /////////////////////////////////////////////////////////////
781 /* Returns the base-2 logarithm of x. Returns -1 if x is not a power
783 Int VG_(log2) ( UInt x )
786 /* Any more than 32 and we overflow anyway... */
787 for (i = 0; i < 32; i++) {
788 if ((1U << i) == x) return i;
793 /* Ditto for 64 bit numbers. */
794 Int VG_(log2_64) ( ULong x )
797 for (i = 0; i < 64; i++) {
798 if ((1ULL << i) == x) return i;
803 // Generic quick sort.
804 void VG_(ssort)( void* base, SizeT nmemb, SizeT size,
805 Int (*compar)(void*, void*) )
807 bm_qsort(base,nmemb,size,compar);
811 // This random number generator is based on the one suggested in Kernighan
812 // and Ritchie's "The C Programming Language".
814 // A pseudo-random number generator returning a random UInt. If pSeed
815 // is NULL, it uses its own seed, which starts at zero. If pSeed is
816 // non-NULL, it uses and updates whatever pSeed points at.
818 static UInt seed = 0;
820 UInt VG_(random)( /*MOD*/UInt* pSeed )
825 *pSeed = (1103515245 * *pSeed + 12345);
829 /*--------------------------------------------------------------------*/
831 /*--------------------------------------------------------------------*/