m_libcbase.c revision 7d9b3af56d1f31210684811fa8cad8c27b00d003
1
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
10   Copyright (C) 2000-2007 Julian Seward
11      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
31#include "pub_core_basics.h"
32#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
53static 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 )
82{
83   Bool neg = False;
84   Long n = 0, digit = 0;
85
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;
95      str++;
96   }
97
98   if (neg) n = -n;
99   if (endptr) *endptr = str;    // Record first failing character.
100   return n;
101}
102
103Long VG_(strtoll10) ( Char* str, Char** endptr )
104{
105   Bool neg = False;
106   Long n = 0, digit = 0;
107
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;
128   Long n = 0, digit = 0;
129
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;
158   Long n = 0, digit = 0;
159
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
215Long VG_(atoll16) ( Char* str )
216{
217   return VG_(strtoll16)(str, NULL);
218}
219
220Long VG_(atoll36) ( Char* str )
221{
222   return VG_(strtoll36)(str, NULL);
223}
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{
469   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   }
497
498   while (sz--)
499      *d++ = *s++;
500
501   return dest;
502}
503
504void* VG_(memset) ( void *dest, Int c, SizeT sz )
505{
506   Char *d = (Char *)dest;
507   while (sz >= 4) {
508      d[0] = c;
509      d[1] = c;
510      d[2] = c;
511      d[3] = c;
512      d += 4;
513      sz -= 4;
514   }
515   while (sz > 0) {
516      d[0] = c;
517      d++;
518      sz--;
519   }
520   return dest;
521}
522
523Int VG_(memcmp) ( const void* s1, const void* s2, SizeT n )
524{
525   Int res;
526   const UChar *p1 = s1;
527   const UChar *p2 = s2;
528   UChar a0;
529   UChar b0;
530
531   while (n != 0) {
532      a0 = p1[0];
533      b0 = p2[0];
534      p1 += 1;
535      p2 += 1;
536      res = a0 - b0;
537      if (res != 0)
538         return res;
539      n -= 1;
540   }
541   return 0;
542}
543
544/* ---------------------------------------------------------------------
545   Misc useful functions
546   ------------------------------------------------------------------ */
547
548/* Returns the base-2 logarithm of x.  Returns -1 if x is not a power of two. */
549Int VG_(log2) ( Int x )
550{
551   Int i;
552   /* Any more than 32 and we overflow anyway... */
553   for (i = 0; i < 32; i++) {
554      if (1 << i == x) return i;
555   }
556   return -1;
557}
558
559
560// Generic shell sort.  Like stdlib.h's qsort().
561void VG_(ssort)( void* base, SizeT nmemb, SizeT size,
562                 Int (*compar)(void*, void*) )
563{
564   Int   incs[14] = { 1, 4, 13, 40, 121, 364, 1093, 3280,
565                      9841, 29524, 88573, 265720,
566                      797161, 2391484 };
567   Int   lo = 0;
568   Int   hi = nmemb-1;
569   Int   i, j, h, bigN, hp;
570
571   bigN = hi - lo + 1; if (bigN < 2) return;
572   hp = 0; while (hp < 14 && incs[hp] < bigN) hp++; hp--;
573
574   #define SORT \
575   for ( ; hp >= 0; hp--) { \
576      h = incs[hp]; \
577      for (i = lo + h; i <= hi; i++) { \
578         ASSIGN(v,0, a,i); \
579         j = i; \
580         while (COMPAR(a,(j-h), v,0) > 0) { \
581            ASSIGN(a,j, a,(j-h)); \
582            j = j - h; \
583            if (j <= (lo + h - 1)) break; \
584         } \
585         ASSIGN(a,j, v,0); \
586      } \
587   }
588
589   // Specialised cases
590   if (sizeof(ULong) == size) {
591
592      #define ASSIGN(dst, dsti, src, srci) \
593      (dst)[(dsti)] = (src)[(srci)];
594
595      #define COMPAR(dst, dsti, src, srci) \
596      compar( (void*)(& (dst)[(dsti)]), (void*)(& (src)[(srci)]) )
597
598      ULong* a = (ULong*)base;
599      ULong  v[1];
600
601      SORT;
602
603   } else if (sizeof(UInt) == size) {
604
605      UInt* a = (UInt*)base;
606      UInt  v[1];
607
608      SORT;
609
610   } else if (sizeof(UShort) == size) {
611      UShort* a = (UShort*)base;
612      UShort  v[1];
613
614      SORT;
615
616   } else if (sizeof(UChar) == size) {
617      UChar* a = (UChar*)base;
618      UChar  v[1];
619
620      SORT;
621
622      #undef ASSIGN
623      #undef COMPAR
624
625   } else if ( (4*sizeof(UWord)) == size ) {
626      /* special-case 4 word-elements.  This captures a lot of cases
627         from symbol table reading/canonicalisaton, because both DiLoc
628         and DiSym are 4 word structures. */
629      HChar* a = base;
630      HChar  v[size];
631
632      #define ASSIGN(dst, dsti, src, srci) \
633       do { UWord* dP = (UWord*)&dst[size*(dsti)]; \
634            UWord* sP = (UWord*)&src[size*(srci)]; \
635            dP[0] = sP[0]; \
636            dP[1] = sP[1]; \
637            dP[2] = sP[2]; \
638            dP[3] = sP[3]; \
639          } while (0)
640
641      #define COMPAR(dst, dsti, src, srci) \
642      compar( &dst[size*(dsti)], &src[size*(srci)] )
643
644      SORT;
645
646      #undef ASSIGN
647      #undef COMPAR
648
649   // General case
650   } else {
651      HChar* a = base;
652      HChar  v[size];      // will be at least 'size' bytes
653
654      #define ASSIGN(dst, dsti, src, srci) \
655      VG_(memcpy)( &dst[size*(dsti)], &src[size*(srci)], size );
656
657      #define COMPAR(dst, dsti, src, srci) \
658      compar( &dst[size*(dsti)], &src[size*(srci)] )
659
660      SORT;
661
662      #undef ASSIGN
663      #undef COMPAR
664   }
665   #undef SORT
666}
667
668// This random number generator is based on the one suggested in Kernighan
669// and Ritchie's "The C Programming Language".
670
671// A pseudo-random number generator returning a random UInt.  If pSeed
672// is NULL, it uses its own seed, which starts at zero.  If pSeed is
673// non-NULL, it uses and updates whatever pSeed points at.
674
675static UInt seed = 0;
676
677UInt VG_(random)( /*MOD*/UInt* pSeed )
678{
679   if (pSeed == NULL)
680      pSeed = &seed;
681
682   *pSeed = (1103515245 * *pSeed + 12345);
683   return *pSeed;
684}
685
686/*--------------------------------------------------------------------*/
687/*--- end                                                          ---*/
688/*--------------------------------------------------------------------*/
689
690