blob: d895bd3b02c2d0f13395b6c3a5e3a8314b117efa [file] [log] [blame]
njn97405b22005-06-02 03:39:33 +00001
2/*--------------------------------------------------------------------*/
3/*--- Entirely standalone libc stuff. m_libcbase.c ---*/
4/*--------------------------------------------------------------------*/
5
6/*
7 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
9
sewardj9ebd6e02007-01-08 06:01:59 +000010 Copyright (C) 2000-2007 Julian Seward
njn97405b22005-06-02 03:39:33 +000011 jseward@acm.org
12
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.
17
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.
22
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
26 02111-1307, USA.
27
28 The GNU General Public License is contained in the file COPYING.
29*/
30
njnc7561b92005-06-19 01:24:32 +000031#include "pub_core_basics.h"
njn97405b22005-06-02 03:39:33 +000032#include "pub_core_libcbase.h"
33
34/* ---------------------------------------------------------------------
35 Char functions.
36 ------------------------------------------------------------------ */
37
38Bool VG_(isspace) ( Char c )
39{
40 return (c == ' ' || c == '\n' || c == '\t' ||
41 c == '\f' || c == '\v' || c == '\r');
42}
43
44Bool VG_(isdigit) ( Char c )
45{
46 return (c >= '0' && c <= '9');
47}
48
49/* ---------------------------------------------------------------------
50 Converting strings to numbers
51 ------------------------------------------------------------------ */
52
njnea5d2352007-11-11 21:58:21 +000053static Bool is_oct_digit(Char c, Long* digit)
54{
55 if (c >= '0' && c <= '7') { *digit = (Long)(c - '0'); return True; }
56 return False;
57}
58
59static Bool is_dec_digit(Char c, Long* digit)
60{
61 if (c >= '0' && c <= '9') { *digit = (Long)(c - '0'); return True; }
62 return False;
63}
64
65static Bool is_hex_digit(Char c, Long* digit)
66{
67 if (c >= '0' && c <= '9') { *digit = (Long)(c - '0'); return True; }
68 if (c >= 'A' && c <= 'F') { *digit = (Long)((c - 'A') + 10); return True; }
69 if (c >= 'a' && c <= 'f') { *digit = (Long)((c - 'a') + 10); return True; }
70 return False;
71}
72
73static Bool is_base36_digit(Char c, Long* digit)
74{
75 if (c >= '0' && c <= '9') { *digit = (Long)(c - '0'); return True; }
76 if (c >= 'A' && c <= 'Z') { *digit = (Long)((c - 'A') + 10); return True; }
77 if (c >= 'a' && c <= 'z') { *digit = (Long)((c - 'a') + 10); return True; }
78 return False;
79}
80
81Long VG_(strtoll8) ( Char* str, Char** endptr )
njn97405b22005-06-02 03:39:33 +000082{
83 Bool neg = False;
njn7d9b3af2007-11-20 07:04:36 +000084 Long n = 0, digit = 0;
njnea5d2352007-11-11 21:58:21 +000085
86 // Skip leading whitespace.
87 while (VG_(isspace)(*str)) str++;
88
89 // Allow a leading '-' or '+'.
90 if (*str == '-') { str++; neg = True; }
91 else if (*str == '+') { str++; }
92
93 while (is_oct_digit(*str, &digit)) {
94 n = 8*n + digit;
njn97405b22005-06-02 03:39:33 +000095 str++;
96 }
njnea5d2352007-11-11 21:58:21 +000097
njn97405b22005-06-02 03:39:33 +000098 if (neg) n = -n;
njnea5d2352007-11-11 21:58:21 +000099 if (endptr) *endptr = str; // Record first failing character.
njn97405b22005-06-02 03:39:33 +0000100 return n;
101}
102
njnea5d2352007-11-11 21:58:21 +0000103Long VG_(strtoll10) ( Char* str, Char** endptr )
104{
105 Bool neg = False;
njn7d9b3af2007-11-20 07:04:36 +0000106 Long n = 0, digit = 0;
njnea5d2352007-11-11 21:58:21 +0000107
108 // Skip leading whitespace.
109 while (VG_(isspace)(*str)) str++;
110
111 // Allow a leading '-' or '+'.
112 if (*str == '-') { str++; neg = True; }
113 else if (*str == '+') { str++; }
114
115 while (is_dec_digit(*str, &digit)) {
116 n = 10*n + digit;
117 str++;
118 }
119
120 if (neg) n = -n;
121 if (endptr) *endptr = str; // Record first failing character.
122 return n;
123}
124
125Long VG_(strtoll16) ( Char* str, Char** endptr )
126{
127 Bool neg = False;
njn7d9b3af2007-11-20 07:04:36 +0000128 Long n = 0, digit = 0;
njnea5d2352007-11-11 21:58:21 +0000129
130 // Skip leading whitespace.
131 while (VG_(isspace)(*str)) str++;
132
133 // Allow a leading '-' or '+'.
134 if (*str == '-') { str++; neg = True; }
135 else if (*str == '+') { str++; }
136
137 // Allow leading "0x", but only if there's a hex digit
138 // following it.
139 if (*str == '0'
140 && (*(str+1) == 'x' || *(str+1) == 'X')
141 && is_hex_digit( *(str+2), &digit )) {
142 str += 2;
143 }
144
145 while (is_hex_digit(*str, &digit)) {
146 n = 16*n + digit;
147 str++;
148 }
149
150 if (neg) n = -n;
151 if (endptr) *endptr = str; // Record first failing character.
152 return n;
153}
154
155Long VG_(strtoll36) ( Char* str, Char** endptr )
156{
157 Bool neg = False;
njn7d9b3af2007-11-20 07:04:36 +0000158 Long n = 0, digit = 0;
njnea5d2352007-11-11 21:58:21 +0000159
160 // Skip leading whitespace.
161 while (VG_(isspace)(*str)) str++;
162
163 // Allow a leading '-' or '+'.
164 if (*str == '-') { str++; neg = True; }
165 else if (*str == '+') { str++; }
166
167 while (is_base36_digit(*str, &digit)) {
168 n = 36*n + digit;
169 str++;
170 }
171
172 if (neg) n = -n;
173 if (endptr) *endptr = str; // Record first failing character.
174 return n;
175}
176
177double VG_(strtod) ( Char* str, Char** endptr )
178{
179 Bool neg = False;
180 Long digit;
181 double n = 0, frac = 0, x = 0.1;
182
183 // Skip leading whitespace.
184 while (VG_(isspace)(*str)) str++;
185
186 // Allow a leading '-' or '+'.
187 if (*str == '-') { str++; neg = True; }
188 else if (*str == '+') { str++; }
189
190 while (is_dec_digit(*str, &digit)) {
191 n = 10*n + digit;
192 str++;
193 }
194
195 if (*str == '.') {
196 str++;
197 while (is_dec_digit(*str, &digit)) {
198 frac += x*digit;
199 x /= 10;
200 str++;
201 }
202 }
203
204 n += frac;
205 if (neg) n = -n;
206 if (endptr) *endptr = str; // Record first failing character.
207 return n;
208}
209
210Long VG_(atoll) ( Char* str )
211{
212 return VG_(strtoll10)(str, NULL);
213}
214
njn5b410922007-09-22 06:23:07 +0000215Long VG_(atoll16) ( Char* str )
216{
njnea5d2352007-11-11 21:58:21 +0000217 return VG_(strtoll16)(str, NULL);
njn5b410922007-09-22 06:23:07 +0000218}
219
njn97405b22005-06-02 03:39:33 +0000220Long VG_(atoll36) ( Char* str )
221{
njnea5d2352007-11-11 21:58:21 +0000222 return VG_(strtoll36)(str, NULL);
njn97405b22005-06-02 03:39:33 +0000223}
224
225/* ---------------------------------------------------------------------
226 String functions
227 ------------------------------------------------------------------ */
228
229Int VG_(strlen) ( const Char* str )
230{
231 Int i = 0;
232 while (str[i] != 0) i++;
233 return i;
234}
235
236Char* VG_(strcat) ( Char* dest, const Char* src )
237{
238 Char* dest_orig = dest;
239 while (*dest) dest++;
240 while (*src) *dest++ = *src++;
241 *dest = 0;
242 return dest_orig;
243}
244
245Char* VG_(strncat) ( Char* dest, const Char* src, SizeT n )
246{
247 Char* dest_orig = dest;
248 while (*dest) dest++;
249 while (*src && n > 0) { *dest++ = *src++; n--; }
250 *dest = 0;
251 return dest_orig;
252}
253
254Char* VG_(strpbrk) ( const Char* s, const Char* accept )
255{
256 const Char* a;
257 while (*s) {
258 a = accept;
259 while (*a)
260 if (*a++ == *s)
261 return (Char *) s;
262 s++;
263 }
264 return NULL;
265}
266
267Char* VG_(strcpy) ( Char* dest, const Char* src )
268{
269 Char* dest_orig = dest;
270 while (*src) *dest++ = *src++;
271 *dest = 0;
272 return dest_orig;
273}
274
275/* Copy bytes, not overrunning the end of dest and always ensuring
276 zero termination. */
277void VG_(strncpy_safely) ( Char* dest, const Char* src, SizeT ndest )
278{
279 Int i = 0;
280 while (True) {
281 dest[i] = 0;
282 if (src[i] == 0) return;
283 if (i >= ndest-1) return;
284 dest[i] = src[i];
285 i++;
286 }
287}
288
289Char* VG_(strncpy) ( Char* dest, const Char* src, SizeT ndest )
290{
291 Int i = 0;
292 while (True) {
293 if (i >= ndest) return dest; /* reached limit */
294 dest[i] = src[i];
295 if (src[i++] == 0) {
296 /* reached NUL; pad rest with zeroes as required */
297 while (i < ndest) dest[i++] = 0;
298 return dest;
299 }
300 }
301}
302
303Int VG_(strcmp) ( const Char* s1, const Char* s2 )
304{
305 while (True) {
306 if (*s1 == 0 && *s2 == 0) return 0;
307 if (*s1 == 0) return -1;
308 if (*s2 == 0) return 1;
309
310 if (*(UChar*)s1 < *(UChar*)s2) return -1;
311 if (*(UChar*)s1 > *(UChar*)s2) return 1;
312
313 s1++; s2++;
314 }
315}
316
317static Bool isterm ( Char c )
318{
319 return ( VG_(isspace)(c) || 0 == c );
320}
321
322Int VG_(strcmp_ws) ( const Char* s1, const Char* s2 )
323{
324 while (True) {
325 if (isterm(*s1) && isterm(*s2)) return 0;
326 if (isterm(*s1)) return -1;
327 if (isterm(*s2)) return 1;
328
329 if (*(UChar*)s1 < *(UChar*)s2) return -1;
330 if (*(UChar*)s1 > *(UChar*)s2) return 1;
331
332 s1++; s2++;
333 }
334}
335
336Int VG_(strncmp) ( const Char* s1, const Char* s2, SizeT nmax )
337{
338 Int n = 0;
339 while (True) {
340 if (n >= nmax) return 0;
341 if (*s1 == 0 && *s2 == 0) return 0;
342 if (*s1 == 0) return -1;
343 if (*s2 == 0) return 1;
344
345 if (*(UChar*)s1 < *(UChar*)s2) return -1;
346 if (*(UChar*)s1 > *(UChar*)s2) return 1;
347
348 s1++; s2++; n++;
349 }
350}
351
352Int VG_(strncmp_ws) ( const Char* s1, const Char* s2, SizeT nmax )
353{
354 Int n = 0;
355 while (True) {
356 if (n >= nmax) return 0;
357 if (isterm(*s1) && isterm(*s2)) return 0;
358 if (isterm(*s1)) return -1;
359 if (isterm(*s2)) return 1;
360
361 if (*(UChar*)s1 < *(UChar*)s2) return -1;
362 if (*(UChar*)s1 > *(UChar*)s2) return 1;
363
364 s1++; s2++; n++;
365 }
366}
367
368Char* VG_(strstr) ( const Char* haystack, Char* needle )
369{
370 Int n;
371 if (haystack == NULL)
372 return NULL;
373 n = VG_(strlen)(needle);
374 while (True) {
375 if (haystack[0] == 0)
376 return NULL;
377 if (VG_(strncmp)(haystack, needle, n) == 0)
378 return (Char*)haystack;
379 haystack++;
380 }
381}
382
383Char* VG_(strchr) ( const Char* s, Char c )
384{
385 while (True) {
386 if (*s == c) return (Char*)s;
387 if (*s == 0) return NULL;
388 s++;
389 }
390}
391
392Char* VG_(strrchr) ( const Char* s, Char c )
393{
394 Int n = VG_(strlen)(s);
395 while (--n > 0) {
396 if (s[n] == c) return (Char*)s + n;
397 }
398 return NULL;
399}
400
401/* ---------------------------------------------------------------------
402 A simple string matching routine, purloined from Hugs98.
403 '*' matches any sequence of zero or more characters
404 '?' matches any single character exactly
405 '\c' matches the character c only (ignoring special chars)
406 c matches the character c only
407 ------------------------------------------------------------------ */
408
409/* Keep track of recursion depth. */
410static Int recDepth;
411
412// Nb: vg_assert disabled because we can't use it from this module...
413static Bool string_match_wrk ( const Char* pat, const Char* str )
414{
415 //vg_assert(recDepth >= 0 && recDepth < 500);
416 recDepth++;
417 for (;;) {
418 switch (*pat) {
419 case '\0':recDepth--;
420 return (*str=='\0');
421 case '*': do {
422 if (string_match_wrk(pat+1,str)) {
423 recDepth--;
424 return True;
425 }
426 } while (*str++);
427 recDepth--;
428 return False;
429 case '?': if (*str++=='\0') {
430 recDepth--;
431 return False;
432 }
433 pat++;
434 break;
435 case '\\':if (*++pat == '\0') {
436 recDepth--;
437 return False; /* spurious trailing \ in pattern */
438 }
439 /* falls through to ... */
440 default : if (*pat++ != *str++) {
441 recDepth--;
442 return False;
443 }
444 break;
445 }
446 }
447}
448
449Bool VG_(string_match) ( const Char* pat, const Char* str )
450{
451 Bool b;
452 recDepth = 0;
453 b = string_match_wrk ( pat, str );
454 //vg_assert(recDepth == 0);
455 /*
456 VG_(printf)("%s %s %s\n",
457 b?"TRUE ":"FALSE", pat, str);
458 */
459 return b;
460}
461
462
463/* ---------------------------------------------------------------------
464 mem* functions
465 ------------------------------------------------------------------ */
466
467void* VG_(memcpy) ( void *dest, const void *src, SizeT sz )
468{
sewardj45f4e7c2005-09-27 19:20:21 +0000469 const UChar* s = (const UChar*)src;
470 UChar* d = (UChar*)dest;
471 const UInt* sI = (const UInt*)src;
472 UInt* dI = (UInt*)dest;
473
474 if (VG_IS_4_ALIGNED(dI) && VG_IS_4_ALIGNED(sI)) {
475 while (sz >= 16) {
476 dI[0] = sI[0];
477 dI[1] = sI[1];
478 dI[2] = sI[2];
479 dI[3] = sI[3];
480 sz -= 16;
481 dI += 4;
482 sI += 4;
483 }
484 if (sz == 0)
485 return dest;
486 while (sz >= 4) {
487 dI[0] = sI[0];
488 sz -= 4;
489 dI += 1;
490 sI += 1;
491 }
492 if (sz == 0)
493 return dest;
494 s = (const UChar*)sI;
495 d = (UChar*)dI;
496 }
njn97405b22005-06-02 03:39:33 +0000497
498 while (sz--)
499 *d++ = *s++;
500
501 return dest;
502}
503
sewardjbbec7722007-11-25 14:08:53 +0000504void* VG_(memmove)(void *dest, const void *src, SizeT sz)
505{
506 SizeT i;
507 if (sz == 0)
508 return dest;
509 if (dest < src) {
510 for (i = 0; i < sz; i++) {
511 ((UChar*)dest)[i] = ((UChar*)src)[i];
512 }
513 }
514 else if (dest > src) {
515 for (i = sz - 1; i >= 0; i--) {
516 ((UChar*)dest)[i] = ((UChar*)src)[i];
517 }
518 }
519 return dest;
520}
521
njn97405b22005-06-02 03:39:33 +0000522void* VG_(memset) ( void *dest, Int c, SizeT sz )
523{
524 Char *d = (Char *)dest;
sewardj3187a4e2005-12-04 23:27:14 +0000525 while (sz >= 4) {
526 d[0] = c;
527 d[1] = c;
528 d[2] = c;
529 d[3] = c;
530 d += 4;
531 sz -= 4;
532 }
533 while (sz > 0) {
534 d[0] = c;
535 d++;
536 sz--;
537 }
njn97405b22005-06-02 03:39:33 +0000538 return dest;
539}
540
541Int VG_(memcmp) ( const void* s1, const void* s2, SizeT n )
542{
543 Int res;
tom151a6392005-11-11 12:30:36 +0000544 const UChar *p1 = s1;
545 const UChar *p2 = s2;
njn97405b22005-06-02 03:39:33 +0000546 UChar a0;
547 UChar b0;
548
549 while (n != 0) {
tom151a6392005-11-11 12:30:36 +0000550 a0 = p1[0];
551 b0 = p2[0];
552 p1 += 1;
553 p2 += 1;
njn97405b22005-06-02 03:39:33 +0000554 res = a0 - b0;
555 if (res != 0)
556 return res;
557 n -= 1;
558 }
559 return 0;
560}
561
562/* ---------------------------------------------------------------------
563 Misc useful functions
564 ------------------------------------------------------------------ */
565
njncda391f2005-12-22 19:50:45 +0000566/* Returns the base-2 logarithm of x. Returns -1 if x is not a power of two. */
njn97405b22005-06-02 03:39:33 +0000567Int VG_(log2) ( Int x )
568{
569 Int i;
570 /* Any more than 32 and we overflow anyway... */
571 for (i = 0; i < 32; i++) {
572 if (1 << i == x) return i;
573 }
574 return -1;
575}
576
577
578// Generic shell sort. Like stdlib.h's qsort().
579void VG_(ssort)( void* base, SizeT nmemb, SizeT size,
580 Int (*compar)(void*, void*) )
581{
582 Int incs[14] = { 1, 4, 13, 40, 121, 364, 1093, 3280,
583 9841, 29524, 88573, 265720,
584 797161, 2391484 };
585 Int lo = 0;
586 Int hi = nmemb-1;
587 Int i, j, h, bigN, hp;
588
589 bigN = hi - lo + 1; if (bigN < 2) return;
590 hp = 0; while (hp < 14 && incs[hp] < bigN) hp++; hp--;
591
592 #define SORT \
593 for ( ; hp >= 0; hp--) { \
594 h = incs[hp]; \
595 for (i = lo + h; i <= hi; i++) { \
596 ASSIGN(v,0, a,i); \
597 j = i; \
598 while (COMPAR(a,(j-h), v,0) > 0) { \
599 ASSIGN(a,j, a,(j-h)); \
600 j = j - h; \
601 if (j <= (lo + h - 1)) break; \
602 } \
603 ASSIGN(a,j, v,0); \
604 } \
605 }
606
607 // Specialised cases
608 if (sizeof(ULong) == size) {
609
610 #define ASSIGN(dst, dsti, src, srci) \
611 (dst)[(dsti)] = (src)[(srci)];
612
613 #define COMPAR(dst, dsti, src, srci) \
614 compar( (void*)(& (dst)[(dsti)]), (void*)(& (src)[(srci)]) )
615
616 ULong* a = (ULong*)base;
617 ULong v[1];
618
619 SORT;
620
621 } else if (sizeof(UInt) == size) {
622
623 UInt* a = (UInt*)base;
624 UInt v[1];
625
626 SORT;
627
628 } else if (sizeof(UShort) == size) {
629 UShort* a = (UShort*)base;
630 UShort v[1];
631
632 SORT;
633
634 } else if (sizeof(UChar) == size) {
635 UChar* a = (UChar*)base;
636 UChar v[1];
637
638 SORT;
639
640 #undef ASSIGN
641 #undef COMPAR
642
sewardj085f9362007-02-08 16:25:56 +0000643 } else if ( (4*sizeof(UWord)) == size ) {
644 /* special-case 4 word-elements. This captures a lot of cases
645 from symbol table reading/canonicalisaton, because both DiLoc
646 and DiSym are 4 word structures. */
647 HChar* a = base;
648 HChar v[size];
649
650 #define ASSIGN(dst, dsti, src, srci) \
651 do { UWord* dP = (UWord*)&dst[size*(dsti)]; \
652 UWord* sP = (UWord*)&src[size*(srci)]; \
653 dP[0] = sP[0]; \
654 dP[1] = sP[1]; \
655 dP[2] = sP[2]; \
656 dP[3] = sP[3]; \
657 } while (0)
658
659 #define COMPAR(dst, dsti, src, srci) \
660 compar( &dst[size*(dsti)], &src[size*(srci)] )
661
662 SORT;
663
664 #undef ASSIGN
665 #undef COMPAR
666
njn97405b22005-06-02 03:39:33 +0000667 // General case
668 } else {
sewardj085f9362007-02-08 16:25:56 +0000669 HChar* a = base;
670 HChar v[size]; // will be at least 'size' bytes
njn97405b22005-06-02 03:39:33 +0000671
672 #define ASSIGN(dst, dsti, src, srci) \
673 VG_(memcpy)( &dst[size*(dsti)], &src[size*(srci)], size );
674
675 #define COMPAR(dst, dsti, src, srci) \
676 compar( &dst[size*(dsti)], &src[size*(srci)] )
677
678 SORT;
679
680 #undef ASSIGN
681 #undef COMPAR
682 }
683 #undef SORT
684}
685
njn9828b342005-07-08 04:08:59 +0000686// This random number generator is based on the one suggested in Kernighan
687// and Ritchie's "The C Programming Language".
sewardj45f4e7c2005-09-27 19:20:21 +0000688
689// A pseudo-random number generator returning a random UInt. If pSeed
690// is NULL, it uses its own seed, which starts at zero. If pSeed is
691// non-NULL, it uses and updates whatever pSeed points at.
692
693static UInt seed = 0;
694
695UInt VG_(random)( /*MOD*/UInt* pSeed )
njn9828b342005-07-08 04:08:59 +0000696{
sewardj45f4e7c2005-09-27 19:20:21 +0000697 if (pSeed == NULL)
698 pSeed = &seed;
699
700 *pSeed = (1103515245 * *pSeed + 12345);
701 return *pSeed;
njn9828b342005-07-08 04:08:59 +0000702}
703
njn97405b22005-06-02 03:39:33 +0000704/*--------------------------------------------------------------------*/
705/*--- end ---*/
706/*--------------------------------------------------------------------*/
707