blob: a84eb34aaf1442d1970f52415e6543806f3c8212 [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
sewardj0f157dd2013-10-18 14:27:36 +000010 Copyright (C) 2000-2013 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"
florian421c26e2014-07-24 12:46:28 +000032#include "pub_core_libcassert.h" // VG_(exit_now)
33#include "pub_core_debuglog.h" // VG_(debugLog)
njn97405b22005-06-02 03:39:33 +000034#include "pub_core_libcbase.h"
35
florian421c26e2014-07-24 12:46:28 +000036
37/* ---------------------------------------------------------------------
florian8f9b0d22014-07-25 08:38:02 +000038 Assert machinery for use in this file. vg_assert cannot be called
florian421c26e2014-07-24 12:46:28 +000039 here due to cyclic dependencies.
40 ------------------------------------------------------------------ */
41#define libcbase_assert(expr) \
florian8f9b0d22014-07-25 08:38:02 +000042 ((void) (LIKELY(expr) ? 0 : \
florian421c26e2014-07-24 12:46:28 +000043 (ML_(libcbase_assert_fail)(#expr, \
44 __FILE__, __LINE__, \
45 __PRETTY_FUNCTION__))))
46
47static void ML_(libcbase_assert_fail)( const HChar *expr,
48 const HChar *file,
49 Int line,
50 const HChar *fn )
51{
52 VG_(debugLog)(0, "libcbase",
53 "Valgrind: FATAL: assertion failed:\n");
54 VG_(debugLog)(0, "libcbase", " %s\n", expr);
55 VG_(debugLog)(0, "libcbase", " at %s:%d (%s)\n", file, line, fn);
56 VG_(debugLog)(0, "libcbase", "Exiting now.\n");
57 VG_(exit_now)(1);
58}
59
njn97405b22005-06-02 03:39:33 +000060/* ---------------------------------------------------------------------
florian19f91bb2012-11-10 22:29:54 +000061 HChar functions.
njn97405b22005-06-02 03:39:33 +000062 ------------------------------------------------------------------ */
63
florian19f91bb2012-11-10 22:29:54 +000064Bool VG_(isspace) ( HChar c )
njn97405b22005-06-02 03:39:33 +000065{
66 return (c == ' ' || c == '\n' || c == '\t' ||
67 c == '\f' || c == '\v' || c == '\r');
68}
69
florian19f91bb2012-11-10 22:29:54 +000070Bool VG_(isdigit) ( HChar c )
njn97405b22005-06-02 03:39:33 +000071{
72 return (c >= '0' && c <= '9');
73}
74
75/* ---------------------------------------------------------------------
76 Converting strings to numbers
77 ------------------------------------------------------------------ */
78
florian19f91bb2012-11-10 22:29:54 +000079static Bool is_dec_digit(HChar c, Long* digit)
njnea5d2352007-11-11 21:58:21 +000080{
81 if (c >= '0' && c <= '9') { *digit = (Long)(c - '0'); return True; }
82 return False;
83}
84
florian19f91bb2012-11-10 22:29:54 +000085static Bool is_hex_digit(HChar c, Long* digit)
njnea5d2352007-11-11 21:58:21 +000086{
87 if (c >= '0' && c <= '9') { *digit = (Long)(c - '0'); return True; }
88 if (c >= 'A' && c <= 'F') { *digit = (Long)((c - 'A') + 10); return True; }
89 if (c >= 'a' && c <= 'f') { *digit = (Long)((c - 'a') + 10); return True; }
90 return False;
91}
92
florian19f91bb2012-11-10 22:29:54 +000093Long VG_(strtoll10) ( const HChar* str, HChar** endptr )
njnea5d2352007-11-11 21:58:21 +000094{
njn8a0b7042009-02-20 06:10:44 +000095 Bool neg = False, converted = False;
njn7d9b3af2007-11-20 07:04:36 +000096 Long n = 0, digit = 0;
florian19f91bb2012-11-10 22:29:54 +000097 const HChar* str0 = str;
njnea5d2352007-11-11 21:58:21 +000098
99 // Skip leading whitespace.
100 while (VG_(isspace)(*str)) str++;
101
102 // Allow a leading '-' or '+'.
103 if (*str == '-') { str++; neg = True; }
104 else if (*str == '+') { str++; }
105
106 while (is_dec_digit(*str, &digit)) {
njn8a0b7042009-02-20 06:10:44 +0000107 converted = True; // Ok, we've actually converted a digit.
njnea5d2352007-11-11 21:58:21 +0000108 n = 10*n + digit;
109 str++;
110 }
111
njn8a0b7042009-02-20 06:10:44 +0000112 if (!converted) str = str0; // If nothing converted, endptr points to
113 if (neg) n = -n; // the start of the string.
florian19f91bb2012-11-10 22:29:54 +0000114 if (endptr) *endptr = (HChar *)str; // Record first failing character.
njnea5d2352007-11-11 21:58:21 +0000115 return n;
116}
117
florian19f91bb2012-11-10 22:29:54 +0000118ULong VG_(strtoull10) ( const HChar* str, HChar** endptr )
sewardj3b290482011-05-06 21:02:55 +0000119{
120 Bool converted = False;
121 ULong n = 0;
122 Long digit = 0;
florian19f91bb2012-11-10 22:29:54 +0000123 const HChar* str0 = str;
sewardj3b290482011-05-06 21:02:55 +0000124
125 // Skip leading whitespace.
126 while (VG_(isspace)(*str)) str++;
127
128 // Allow a leading '+'.
129 if (*str == '+') { str++; }
130
131 while (is_dec_digit(*str, &digit)) {
132 converted = True; // Ok, we've actually converted a digit.
133 n = 10*n + digit;
134 str++;
135 }
136
137 if (!converted) str = str0; // If nothing converted, endptr points to
138 // the start of the string.
florian19f91bb2012-11-10 22:29:54 +0000139 if (endptr) *endptr = (HChar *)str; // Record first failing character.
sewardj3b290482011-05-06 21:02:55 +0000140 return n;
141}
142
florian19f91bb2012-11-10 22:29:54 +0000143Long VG_(strtoll16) ( const HChar* str, HChar** endptr )
njnea5d2352007-11-11 21:58:21 +0000144{
njn8a0b7042009-02-20 06:10:44 +0000145 Bool neg = False, converted = False;
njn7d9b3af2007-11-20 07:04:36 +0000146 Long n = 0, digit = 0;
florian19f91bb2012-11-10 22:29:54 +0000147 const HChar* str0 = str;
njnea5d2352007-11-11 21:58:21 +0000148
149 // Skip leading whitespace.
150 while (VG_(isspace)(*str)) str++;
151
152 // Allow a leading '-' or '+'.
153 if (*str == '-') { str++; neg = True; }
154 else if (*str == '+') { str++; }
155
156 // Allow leading "0x", but only if there's a hex digit
157 // following it.
158 if (*str == '0'
159 && (*(str+1) == 'x' || *(str+1) == 'X')
160 && is_hex_digit( *(str+2), &digit )) {
161 str += 2;
162 }
163
164 while (is_hex_digit(*str, &digit)) {
njn8a0b7042009-02-20 06:10:44 +0000165 converted = True; // Ok, we've actually converted a digit.
njnea5d2352007-11-11 21:58:21 +0000166 n = 16*n + digit;
167 str++;
168 }
169
njn8a0b7042009-02-20 06:10:44 +0000170 if (!converted) str = str0; // If nothing converted, endptr points to
171 if (neg) n = -n; // the start of the string.
florian19f91bb2012-11-10 22:29:54 +0000172 if (endptr) *endptr = (HChar *)str; // Record first failing character.
njnea5d2352007-11-11 21:58:21 +0000173 return n;
174}
175
florian19f91bb2012-11-10 22:29:54 +0000176ULong VG_(strtoull16) ( const HChar* str, HChar** endptr )
sewardj3b290482011-05-06 21:02:55 +0000177{
178 Bool converted = False;
179 ULong n = 0;
180 Long digit = 0;
florian19f91bb2012-11-10 22:29:54 +0000181 const HChar* str0 = str;
sewardj3b290482011-05-06 21:02:55 +0000182
183 // Skip leading whitespace.
184 while (VG_(isspace)(*str)) str++;
185
186 // Allow a leading '+'.
187 if (*str == '+') { str++; }
188
189 // Allow leading "0x", but only if there's a hex digit
190 // following it.
191 if (*str == '0'
192 && (*(str+1) == 'x' || *(str+1) == 'X')
193 && is_hex_digit( *(str+2), &digit )) {
194 str += 2;
195 }
196
197 while (is_hex_digit(*str, &digit)) {
198 converted = True; // Ok, we've actually converted a digit.
199 n = 16*n + digit;
200 str++;
201 }
202
203 if (!converted) str = str0; // If nothing converted, endptr points to
204 // the start of the string.
florian19f91bb2012-11-10 22:29:54 +0000205 if (endptr) *endptr = (HChar *)str; // Record first failing character.
sewardj3b290482011-05-06 21:02:55 +0000206 return n;
207}
208
florian19f91bb2012-11-10 22:29:54 +0000209double VG_(strtod) ( const HChar* str, HChar** endptr )
njnea5d2352007-11-11 21:58:21 +0000210{
211 Bool neg = False;
212 Long digit;
213 double n = 0, frac = 0, x = 0.1;
214
215 // Skip leading whitespace.
216 while (VG_(isspace)(*str)) str++;
217
218 // Allow a leading '-' or '+'.
219 if (*str == '-') { str++; neg = True; }
220 else if (*str == '+') { str++; }
221
222 while (is_dec_digit(*str, &digit)) {
223 n = 10*n + digit;
224 str++;
225 }
226
227 if (*str == '.') {
228 str++;
229 while (is_dec_digit(*str, &digit)) {
230 frac += x*digit;
231 x /= 10;
232 str++;
233 }
234 }
235
236 n += frac;
237 if (neg) n = -n;
florian19f91bb2012-11-10 22:29:54 +0000238 if (endptr) *endptr = (HChar *)str; // Record first failing character.
njnea5d2352007-11-11 21:58:21 +0000239 return n;
240}
241
florian19f91bb2012-11-10 22:29:54 +0000242HChar VG_(tolower) ( HChar c )
njnf76d27a2009-05-28 01:53:07 +0000243{
244 if ( c >= 'A' && c <= 'Z' ) {
245 return c - 'A' + 'a';
246 } else {
247 return c;
248 }
249}
250
njn97405b22005-06-02 03:39:33 +0000251/* ---------------------------------------------------------------------
252 String functions
253 ------------------------------------------------------------------ */
254
florian19f91bb2012-11-10 22:29:54 +0000255SizeT VG_(strlen) ( const HChar* str )
njn97405b22005-06-02 03:39:33 +0000256{
sewardj4f2683a2008-10-26 11:53:30 +0000257 SizeT i = 0;
njn97405b22005-06-02 03:39:33 +0000258 while (str[i] != 0) i++;
259 return i;
260}
261
florian19f91bb2012-11-10 22:29:54 +0000262HChar* VG_(strcat) ( HChar* dest, const HChar* src )
njn97405b22005-06-02 03:39:33 +0000263{
florian19f91bb2012-11-10 22:29:54 +0000264 HChar* dest_orig = dest;
njn97405b22005-06-02 03:39:33 +0000265 while (*dest) dest++;
266 while (*src) *dest++ = *src++;
267 *dest = 0;
268 return dest_orig;
269}
270
florian19f91bb2012-11-10 22:29:54 +0000271HChar* VG_(strncat) ( HChar* dest, const HChar* src, SizeT n )
njn97405b22005-06-02 03:39:33 +0000272{
florian19f91bb2012-11-10 22:29:54 +0000273 HChar* dest_orig = dest;
njn97405b22005-06-02 03:39:33 +0000274 while (*dest) dest++;
275 while (*src && n > 0) { *dest++ = *src++; n--; }
276 *dest = 0;
277 return dest_orig;
278}
279
florian19f91bb2012-11-10 22:29:54 +0000280HChar* VG_(strpbrk) ( const HChar* s, const HChar* accpt )
njn97405b22005-06-02 03:39:33 +0000281{
florian19f91bb2012-11-10 22:29:54 +0000282 const HChar* a;
njn97405b22005-06-02 03:39:33 +0000283 while (*s) {
njnf9dcb3b2009-05-19 05:50:34 +0000284 a = accpt;
njn97405b22005-06-02 03:39:33 +0000285 while (*a)
286 if (*a++ == *s)
florian19f91bb2012-11-10 22:29:54 +0000287 return (HChar *)s;
njn97405b22005-06-02 03:39:33 +0000288 s++;
289 }
290 return NULL;
291}
292
florian19f91bb2012-11-10 22:29:54 +0000293HChar* VG_(strcpy) ( HChar* dest, const HChar* src )
njn97405b22005-06-02 03:39:33 +0000294{
florian19f91bb2012-11-10 22:29:54 +0000295 HChar* dest_orig = dest;
njn97405b22005-06-02 03:39:33 +0000296 while (*src) *dest++ = *src++;
297 *dest = 0;
298 return dest_orig;
299}
300
301/* Copy bytes, not overrunning the end of dest and always ensuring
302 zero termination. */
florian19f91bb2012-11-10 22:29:54 +0000303void VG_(strncpy_safely) ( HChar* dest, const HChar* src, SizeT ndest )
njn97405b22005-06-02 03:39:33 +0000304{
florian421c26e2014-07-24 12:46:28 +0000305 libcbase_assert(ndest > 0);
306
florian4f11c7f2014-07-24 12:50:03 +0000307 VG_(strncpy)(dest, src, ndest);
308 dest[ndest - 1] = '\0';
njn97405b22005-06-02 03:39:33 +0000309}
310
florian19f91bb2012-11-10 22:29:54 +0000311HChar* VG_(strncpy) ( HChar* dest, const HChar* src, SizeT ndest )
njn97405b22005-06-02 03:39:33 +0000312{
sewardj4f2683a2008-10-26 11:53:30 +0000313 SizeT i = 0;
njn97405b22005-06-02 03:39:33 +0000314 while (True) {
315 if (i >= ndest) return dest; /* reached limit */
316 dest[i] = src[i];
317 if (src[i++] == 0) {
318 /* reached NUL; pad rest with zeroes as required */
319 while (i < ndest) dest[i++] = 0;
320 return dest;
321 }
322 }
323}
324
florian19f91bb2012-11-10 22:29:54 +0000325Int VG_(strcmp) ( const HChar* s1, const HChar* s2 )
njn97405b22005-06-02 03:39:33 +0000326{
327 while (True) {
florian3e798632012-11-24 19:41:54 +0000328 if (*(const UChar*)s1 < *(const UChar*)s2) return -1;
329 if (*(const UChar*)s1 > *(const UChar*)s2) return 1;
njn97405b22005-06-02 03:39:33 +0000330
philippe56ddd5b2012-07-26 22:44:07 +0000331 /* *s1 == *s2 */
332 if (*s1 == 0) return 0;
333
njn97405b22005-06-02 03:39:33 +0000334 s1++; s2++;
335 }
336}
337
florian19f91bb2012-11-10 22:29:54 +0000338Int VG_(strcasecmp) ( const HChar* s1, const HChar* s2 )
njnf76d27a2009-05-28 01:53:07 +0000339{
340 while (True) {
341 UChar c1 = (UChar)VG_(tolower)(*s1);
342 UChar c2 = (UChar)VG_(tolower)(*s2);
njnf76d27a2009-05-28 01:53:07 +0000343 if (c1 < c2) return -1;
344 if (c1 > c2) return 1;
philippe56ddd5b2012-07-26 22:44:07 +0000345
346 /* c1 == c2 */
347 if (c1 == 0) return 0;
njnf76d27a2009-05-28 01:53:07 +0000348
349 s1++; s2++;
350 }
351}
352
florian19f91bb2012-11-10 22:29:54 +0000353Int VG_(strncmp) ( const HChar* s1, const HChar* s2, SizeT nmax )
njn97405b22005-06-02 03:39:33 +0000354{
sewardj4f2683a2008-10-26 11:53:30 +0000355 SizeT n = 0;
njn97405b22005-06-02 03:39:33 +0000356 while (True) {
357 if (n >= nmax) return 0;
florian3e798632012-11-24 19:41:54 +0000358 if (*(const UChar*)s1 < *(const UChar*)s2) return -1;
359 if (*(const UChar*)s1 > *(const UChar*)s2) return 1;
philippe56ddd5b2012-07-26 22:44:07 +0000360
361 /* *s1 == *s2 */
362 if (*s1 == 0) return 0;
njn97405b22005-06-02 03:39:33 +0000363
364 s1++; s2++; n++;
365 }
366}
367
florian19f91bb2012-11-10 22:29:54 +0000368Int VG_(strncasecmp) ( const HChar* s1, const HChar* s2, SizeT nmax )
njnf76d27a2009-05-28 01:53:07 +0000369{
370 Int n = 0;
371 while (True) {
372 UChar c1;
373 UChar c2;
374 if (n >= nmax) return 0;
375 c1 = (UChar)VG_(tolower)(*s1);
376 c2 = (UChar)VG_(tolower)(*s2);
njnf76d27a2009-05-28 01:53:07 +0000377 if (c1 < c2) return -1;
378 if (c1 > c2) return 1;
379
philippe56ddd5b2012-07-26 22:44:07 +0000380 /* c1 == c2 */
381 if (c1 == 0) return 0;
382
njnf76d27a2009-05-28 01:53:07 +0000383 s1++; s2++; n++;
384 }
385}
386
florian19f91bb2012-11-10 22:29:54 +0000387HChar* VG_(strstr) ( const HChar* haystack, const HChar* needle )
njn97405b22005-06-02 03:39:33 +0000388{
sewardj4f2683a2008-10-26 11:53:30 +0000389 SizeT n;
njn97405b22005-06-02 03:39:33 +0000390 if (haystack == NULL)
391 return NULL;
392 n = VG_(strlen)(needle);
393 while (True) {
394 if (haystack[0] == 0)
395 return NULL;
396 if (VG_(strncmp)(haystack, needle, n) == 0)
florian19f91bb2012-11-10 22:29:54 +0000397 return (HChar*)haystack;
njn97405b22005-06-02 03:39:33 +0000398 haystack++;
399 }
400}
401
florian19f91bb2012-11-10 22:29:54 +0000402HChar* VG_(strcasestr) ( const HChar* haystack, const HChar* needle )
njnf76d27a2009-05-28 01:53:07 +0000403{
404 Int n;
405 if (haystack == NULL)
406 return NULL;
407 n = VG_(strlen)(needle);
408 while (True) {
409 if (haystack[0] == 0)
410 return NULL;
411 if (VG_(strncasecmp)(haystack, needle, n) == 0)
florian19f91bb2012-11-10 22:29:54 +0000412 return (HChar*)haystack;
njnf76d27a2009-05-28 01:53:07 +0000413 haystack++;
414 }
415}
416
florian19f91bb2012-11-10 22:29:54 +0000417HChar* VG_(strchr) ( const HChar* s, HChar c )
njn97405b22005-06-02 03:39:33 +0000418{
419 while (True) {
florian19f91bb2012-11-10 22:29:54 +0000420 if (*s == c) return (HChar *)s;
njn97405b22005-06-02 03:39:33 +0000421 if (*s == 0) return NULL;
422 s++;
423 }
424}
425
florian19f91bb2012-11-10 22:29:54 +0000426HChar* VG_(strrchr) ( const HChar* s, HChar c )
njn97405b22005-06-02 03:39:33 +0000427{
428 Int n = VG_(strlen)(s);
429 while (--n > 0) {
florian19f91bb2012-11-10 22:29:54 +0000430 if (s[n] == c) return (HChar *)s + n;
njn97405b22005-06-02 03:39:33 +0000431 }
432 return NULL;
433}
434
sewardj3b290482011-05-06 21:02:55 +0000435/* (code copied from glib then updated to valgrind types) */
florian19f91bb2012-11-10 22:29:54 +0000436static HChar *olds;
437HChar *
438VG_(strtok) (HChar *s, const HChar *delim)
sewardj3b290482011-05-06 21:02:55 +0000439{
440 return VG_(strtok_r) (s, delim, &olds);
441}
442
florian19f91bb2012-11-10 22:29:54 +0000443HChar *
444VG_(strtok_r) (HChar* s, const HChar* delim, HChar** saveptr)
sewardj3b290482011-05-06 21:02:55 +0000445{
florian19f91bb2012-11-10 22:29:54 +0000446 HChar *token;
sewardj3b290482011-05-06 21:02:55 +0000447
448 if (s == NULL)
449 s = *saveptr;
450
451 /* Scan leading delimiters. */
452 s += VG_(strspn (s, delim));
453 if (*s == '\0')
454 {
455 *saveptr = s;
456 return NULL;
457 }
458
459 /* Find the end of the token. */
460 token = s;
461 s = VG_(strpbrk (token, delim));
462 if (s == NULL)
463 /* This token finishes the string. */
464 *saveptr = token + VG_(strlen) (token);
465 else
466 {
467 /* Terminate the token and make OLDS point past it. */
468 *s = '\0';
469 *saveptr = s + 1;
470 }
471 return token;
472}
473
florian19f91bb2012-11-10 22:29:54 +0000474static Bool isHex ( HChar c )
sewardj3b290482011-05-06 21:02:55 +0000475{
476 return ((c >= '0' && c <= '9') ||
477 (c >= 'a' && c <= 'f') ||
478 (c >= 'A' && c <= 'F'));
479}
480
florian19f91bb2012-11-10 22:29:54 +0000481static UInt fromHex ( HChar c )
sewardj3b290482011-05-06 21:02:55 +0000482{
483 if (c >= '0' && c <= '9')
484 return (UInt)c - (UInt)'0';
485 if (c >= 'a' && c <= 'f')
486 return 10 + (UInt)c - (UInt)'a';
487 if (c >= 'A' && c <= 'F')
488 return 10 + (UInt)c - (UInt)'A';
489 /*NOTREACHED*/
490 // ??? need to vg_assert(0);
491 return 0;
492}
493
florian19f91bb2012-11-10 22:29:54 +0000494Bool VG_(parse_Addr) ( const HChar** ppc, Addr* result )
sewardj3b290482011-05-06 21:02:55 +0000495{
496 Int used, limit = 2 * sizeof(Addr);
497 if (**ppc != '0')
498 return False;
499 (*ppc)++;
500 if (**ppc != 'x')
501 return False;
502 (*ppc)++;
503 *result = 0;
504 used = 0;
505 while (isHex(**ppc)) {
506 // ??? need to vg_assert(d < fromHex(**ppc));
507 *result = ((*result) << 4) | fromHex(**ppc);
508 (*ppc)++;
509 used++;
510 if (used > limit) return False;
511 }
512 if (used == 0)
513 return False;
514 return True;
515}
516
philippe0c2923f2014-04-19 09:52:32 +0000517Bool VG_(parse_enum_set) ( const HChar *tokens,
518 const HChar *input,
519 UInt *enum_set)
520{
521 const SizeT tokens_len = VG_(strlen)(tokens);
522 if (tokens_len > 1000) return False; /* "obviously invalid" */
523 HChar tok_tokens[tokens_len+1];
524 HChar *tokens_saveptr;
525 HChar *token;
526 UInt token_nr = 0;
527 UInt all_set = 0;
528
529 const SizeT input_len = VG_(strlen)(input);
530 if (input_len > 1000) return False; /* "obviously invalid" */
531 HChar tok_input[input_len+1];
532 HChar *input_saveptr;
533 HChar *input_word;
534 UInt word_nr = 0;
535 UInt known_words = 0;
536 Bool seen_all_kw = False;
537 Bool seen_none_kw = False;
538
539 *enum_set = 0;
540
541 VG_(strcpy) (tok_input, input);
542 for (input_word = VG_(strtok_r)(tok_input, ",", &input_saveptr);
543 input_word;
544 input_word = VG_(strtok_r)(NULL, ",", &input_saveptr)) {
545 word_nr++;
546 if (0 == VG_(strcmp)(input_word, "all")) {
547 seen_all_kw = True;
548 known_words++;
549 } else if (0 == VG_(strcmp)(input_word, "none")) {
550 seen_none_kw = True;
551 known_words++;
552 }
553
554 // Scan tokens + compute all_set. Do that even if all or none was
555 // recognised to have a correct value for all_set when exiting
556 // of the 'input' loop.
557 all_set = 0;
558 token_nr = 0;
559 VG_(strcpy) (tok_tokens, tokens);
560 for (token = VG_(strtok_r)(tok_tokens, ",", &tokens_saveptr);
561 token;
562 token = VG_(strtok_r)(NULL, ",", &tokens_saveptr)) {
563 if (0 != VG_(strcmp)(token, "-")) {
564 if (0 == VG_(strcmp)(input_word, token)) {
565 *enum_set |= 1 << token_nr;
566 known_words++;
567 }
568 all_set |= 1 << token_nr;
569 }
570 token_nr++;
571 }
572 }
573
574 if (known_words != word_nr)
575 return False; // One or more input_words not recognised.
576 if (seen_all_kw) {
577 if (seen_none_kw || *enum_set)
578 return False; // mixing all with either none or a specific value.
579 *enum_set = all_set;
580 } else if (seen_none_kw) {
581 if (seen_all_kw || *enum_set)
582 return False; // mixing none with either all or a specific value.
583 *enum_set = 0;
584 } else {
585 // seen neither all or none, we must see at least one value
586 if (*enum_set == 0)
587 return False;
588 }
589
590 return True;
591}
592
florian19f91bb2012-11-10 22:29:54 +0000593SizeT VG_(strspn) ( const HChar* s, const HChar* accpt )
sewardj4f2683a2008-10-26 11:53:30 +0000594{
florian19f91bb2012-11-10 22:29:54 +0000595 const HChar *p, *a;
sewardj4f2683a2008-10-26 11:53:30 +0000596 SizeT count = 0;
597 for (p = s; *p != '\0'; ++p) {
njnf9dcb3b2009-05-19 05:50:34 +0000598 for (a = accpt; *a != '\0'; ++a)
sewardj4f2683a2008-10-26 11:53:30 +0000599 if (*p == *a)
600 break;
601 if (*a == '\0')
602 return count;
603 else
604 ++count;
605 }
606 return count;
607}
608
florian19f91bb2012-11-10 22:29:54 +0000609SizeT VG_(strcspn) ( const HChar* s, const HChar* reject )
sewardj4f2683a2008-10-26 11:53:30 +0000610{
611 SizeT count = 0;
612 while (*s != '\0') {
613 if (VG_(strchr) (reject, *s++) == NULL)
614 ++count;
615 else
616 return count;
617 }
618 return count;
619}
620
621
njn97405b22005-06-02 03:39:33 +0000622/* ---------------------------------------------------------------------
njn97405b22005-06-02 03:39:33 +0000623 mem* functions
624 ------------------------------------------------------------------ */
625
626void* VG_(memcpy) ( void *dest, const void *src, SizeT sz )
627{
sewardj45f4e7c2005-09-27 19:20:21 +0000628 const UChar* s = (const UChar*)src;
629 UChar* d = (UChar*)dest;
630 const UInt* sI = (const UInt*)src;
631 UInt* dI = (UInt*)dest;
632
633 if (VG_IS_4_ALIGNED(dI) && VG_IS_4_ALIGNED(sI)) {
634 while (sz >= 16) {
635 dI[0] = sI[0];
636 dI[1] = sI[1];
637 dI[2] = sI[2];
638 dI[3] = sI[3];
639 sz -= 16;
640 dI += 4;
641 sI += 4;
642 }
643 if (sz == 0)
644 return dest;
645 while (sz >= 4) {
646 dI[0] = sI[0];
647 sz -= 4;
648 dI += 1;
649 sI += 1;
650 }
651 if (sz == 0)
652 return dest;
653 s = (const UChar*)sI;
654 d = (UChar*)dI;
655 }
njn97405b22005-06-02 03:39:33 +0000656
sewardj5d616df2013-07-02 08:07:15 +0000657 /* If we're unlucky, the alignment constraints for the fast case
658 above won't apply, and we'll have to to it all here. Hence the
659 unrolling. */
660 while (sz >= 4) {
661 d[0] = s[0];
662 d[1] = s[1];
663 d[2] = s[2];
664 d[3] = s[3];
665 d += 4;
666 s += 4;
667 sz -= 4;
668 }
669 while (sz >= 1) {
670 d[0] = s[0];
671 d += 1;
672 s += 1;
673 sz -= 1;
674 }
njn97405b22005-06-02 03:39:33 +0000675
676 return dest;
677}
678
sewardjbbec7722007-11-25 14:08:53 +0000679void* VG_(memmove)(void *dest, const void *src, SizeT sz)
680{
681 SizeT i;
682 if (sz == 0)
683 return dest;
684 if (dest < src) {
685 for (i = 0; i < sz; i++) {
florian3e798632012-11-24 19:41:54 +0000686 ((UChar*)dest)[i] = ((const UChar*)src)[i];
sewardjbbec7722007-11-25 14:08:53 +0000687 }
688 }
689 else if (dest > src) {
tom4634b012009-11-03 21:14:31 +0000690 for (i = 0; i < sz; i++) {
florian3e798632012-11-24 19:41:54 +0000691 ((UChar*)dest)[sz-i-1] = ((const UChar*)src)[sz-i-1];
sewardjbbec7722007-11-25 14:08:53 +0000692 }
693 }
694 return dest;
695}
696
sewardjb8b79ad2008-03-03 01:35:41 +0000697void* VG_(memset) ( void *destV, Int c, SizeT sz )
njn97405b22005-06-02 03:39:33 +0000698{
sewardjb8b79ad2008-03-03 01:35:41 +0000699 Int c4;
florian19f91bb2012-11-10 22:29:54 +0000700 HChar* d = (HChar*)destV;
sewardjb8b79ad2008-03-03 01:35:41 +0000701 while ((!VG_IS_4_ALIGNED(d)) && sz >= 1) {
sewardj3187a4e2005-12-04 23:27:14 +0000702 d[0] = c;
703 d++;
704 sz--;
705 }
sewardjb8b79ad2008-03-03 01:35:41 +0000706 if (sz == 0)
707 return destV;
708 c4 = c & 0xFF;
709 c4 |= (c4 << 8);
710 c4 |= (c4 << 16);
711 while (sz >= 16) {
712 ((Int*)d)[0] = c4;
713 ((Int*)d)[1] = c4;
714 ((Int*)d)[2] = c4;
715 ((Int*)d)[3] = c4;
716 d += 16;
717 sz -= 16;
718 }
719 while (sz >= 4) {
720 ((Int*)d)[0] = c4;
721 d += 4;
722 sz -= 4;
723 }
724 while (sz >= 1) {
725 d[0] = c;
726 d++;
727 sz--;
728 }
729 return destV;
njn97405b22005-06-02 03:39:33 +0000730}
731
732Int VG_(memcmp) ( const void* s1, const void* s2, SizeT n )
733{
734 Int res;
tom151a6392005-11-11 12:30:36 +0000735 const UChar *p1 = s1;
736 const UChar *p2 = s2;
njn97405b22005-06-02 03:39:33 +0000737 UChar a0;
738 UChar b0;
739
740 while (n != 0) {
tom151a6392005-11-11 12:30:36 +0000741 a0 = p1[0];
742 b0 = p2[0];
743 p1 += 1;
744 p2 += 1;
njn97405b22005-06-02 03:39:33 +0000745 res = a0 - b0;
746 if (res != 0)
747 return res;
748 n -= 1;
749 }
750 return 0;
751}
752
753/* ---------------------------------------------------------------------
754 Misc useful functions
755 ------------------------------------------------------------------ */
756
sewardjb8b79ad2008-03-03 01:35:41 +0000757/////////////////////////////////////////////////////////////
758/////////////////////////////////////////////////////////////
759/// begin Bentley-McIlroy style quicksort
760/// See "Engineering a Sort Function". Jon L Bentley, M. Douglas
761/// McIlroy. Software Practice and Experience Vol 23(11), Nov 1993.
762
763#define BM_MIN(a, b) \
764 (a) < (b) ? a : b
765
766#define BM_SWAPINIT(a, es) \
767 swaptype = ((a-(Char*)0) | es) % sizeof(Word) ? 2 \
768 : es > (SizeT)sizeof(Word) ? 1 \
769 : 0
770
771#define BM_EXCH(a, b, t) \
772 (t = a, a = b, b = t)
773
774#define BM_SWAP(a, b) \
775 swaptype != 0 \
776 ? bm_swapfunc(a, b, es, swaptype) \
777 : (void)BM_EXCH(*(Word*)(a), *(Word*)(b), t)
778
779#define BM_VECSWAP(a, b, n) \
780 if (n > 0) bm_swapfunc(a, b, n, swaptype)
781
782#define BM_PVINIT(pv, pm) \
783 if (swaptype != 0) \
784 pv = a, BM_SWAP(pv, pm); \
785 else \
786 pv = (Char*)&v, v = *(Word*)pm
787
788static Char* bm_med3 ( Char* a, Char* b, Char* c,
florian6bd9dc12012-11-23 16:17:43 +0000789 Int (*cmp)(const void*, const void*) ) {
sewardjb8b79ad2008-03-03 01:35:41 +0000790 return cmp(a, b) < 0
791 ? (cmp(b, c) < 0 ? b : cmp(a, c) < 0 ? c : a)
792 : (cmp(b, c) > 0 ? b : cmp(a, c) > 0 ? c : a);
793}
794
795static void bm_swapfunc ( Char* a, Char* b, SizeT n, Int swaptype )
796{
797 if (swaptype <= 1) {
798 Word t;
799 for ( ; n > 0; a += sizeof(Word), b += sizeof(Word),
800 n -= sizeof(Word))
801 BM_EXCH(*(Word*)a, *(Word*)b, t);
802 } else {
803 Char t;
804 for ( ; n > 0; a += 1, b += 1, n -= 1)
805 BM_EXCH(*a, *b, t);
806 }
807}
808
809static void bm_qsort ( Char* a, SizeT n, SizeT es,
florian6bd9dc12012-11-23 16:17:43 +0000810 Int (*cmp)(const void*, const void*) )
sewardjb8b79ad2008-03-03 01:35:41 +0000811{
812 Char *pa, *pb, *pc, *pd, *pl, *pm, *pn, *pv;
813 Int r, swaptype;
814 Word t, v;
815 SizeT s, s1, s2;
816 tailcall:
817 BM_SWAPINIT(a, es);
818 if (n < 7) {
819 for (pm = a + es; pm < a + n*es; pm += es)
820 for (pl = pm; pl > a && cmp(pl-es, pl) > 0; pl -= es)
821 BM_SWAP(pl, pl-es);
822 return;
823 }
824 pm = a + (n/2)*es;
825 if (n > 7) {
826 pl = a;
827 pn = a + (n-1)*es;
828 if (n > 40) {
829 s = (n/8)*es;
830 pl = bm_med3(pl, pl+s, pl+2*s, cmp);
831 pm = bm_med3(pm-s, pm, pm+s, cmp);
832 pn = bm_med3(pn-2*s, pn-s, pn, cmp);
833 }
834 pm = bm_med3(pl, pm, pn, cmp);
835 }
836 BM_PVINIT(pv, pm);
837 pa = pb = a;
838 pc = pd = a + (n-1)*es;
839 for (;;) {
840 while (pb <= pc && (r = cmp(pb, pv)) <= 0) {
841 if (r == 0) { BM_SWAP(pa, pb); pa += es; }
842 pb += es;
843 }
844 while (pc >= pb && (r = cmp(pc, pv)) >= 0) {
845 if (r == 0) { BM_SWAP(pc, pd); pd -= es; }
846 pc -= es;
847 }
848 if (pb > pc) break;
849 BM_SWAP(pb, pc);
850 pb += es;
851 pc -= es;
852 }
853 pn = a + n*es;
854 s = BM_MIN(pa-a, pb-pa ); BM_VECSWAP(a, pb-s, s);
855 s = BM_MIN(pd-pc, pn-pd-es); BM_VECSWAP(pb, pn-s, s);
856 /* Now recurse. Do the smaller partition first with an explicit
857 recursion, then do the larger partition using a tail call.
858 Except we can't rely on gcc to implement a tail call in any sane
859 way, so simply jump back to the start. This guarantees stack
860 growth can never exceed O(log N) even in the worst case. */
861 s1 = pb-pa;
862 s2 = pd-pc;
863 if (s1 < s2) {
864 if (s1 > es) {
865 bm_qsort(a, s1/es, es, cmp);
866 }
867 if (s2 > es) {
868 /* bm_qsort(pn-s2, s2/es, es, cmp); */
869 a = pn-s2; n = s2/es; es = es; cmp = cmp;
870 goto tailcall;
871 }
872 } else {
873 if (s2 > es) {
874 bm_qsort(pn-s2, s2/es, es, cmp);
875 }
876 if (s1 > es) {
877 /* bm_qsort(a, s1/es, es, cmp); */
878 a = a; n = s1/es; es = es; cmp = cmp;
879 goto tailcall;
880 }
881 }
882}
883
884#undef BM_MIN
885#undef BM_SWAPINIT
886#undef BM_EXCH
887#undef BM_SWAP
888#undef BM_VECSWAP
889#undef BM_PVINIT
890
891/// end Bentley-McIlroy style quicksort
892/////////////////////////////////////////////////////////////
893/////////////////////////////////////////////////////////////
894
895/* Returns the base-2 logarithm of x. Returns -1 if x is not a power
896 of two. */
897Int VG_(log2) ( UInt x )
njn97405b22005-06-02 03:39:33 +0000898{
899 Int i;
900 /* Any more than 32 and we overflow anyway... */
901 for (i = 0; i < 32; i++) {
sewardjb8b79ad2008-03-03 01:35:41 +0000902 if ((1U << i) == x) return i;
njn97405b22005-06-02 03:39:33 +0000903 }
904 return -1;
905}
906
sewardjaebbf1c2011-06-13 13:14:00 +0000907/* Ditto for 64 bit numbers. */
908Int VG_(log2_64) ( ULong x )
909{
910 Int i;
911 for (i = 0; i < 64; i++) {
912 if ((1ULL << i) == x) return i;
913 }
914 return -1;
915}
njn97405b22005-06-02 03:39:33 +0000916
njnfab29902008-03-03 02:15:03 +0000917// Generic quick sort.
njn97405b22005-06-02 03:39:33 +0000918void VG_(ssort)( void* base, SizeT nmemb, SizeT size,
florian6bd9dc12012-11-23 16:17:43 +0000919 Int (*compar)(const void*, const void*) )
njn97405b22005-06-02 03:39:33 +0000920{
sewardjb8b79ad2008-03-03 01:35:41 +0000921 bm_qsort(base,nmemb,size,compar);
njn97405b22005-06-02 03:39:33 +0000922}
923
sewardjb8b79ad2008-03-03 01:35:41 +0000924
njn9828b342005-07-08 04:08:59 +0000925// This random number generator is based on the one suggested in Kernighan
926// and Ritchie's "The C Programming Language".
sewardj45f4e7c2005-09-27 19:20:21 +0000927
928// A pseudo-random number generator returning a random UInt. If pSeed
929// is NULL, it uses its own seed, which starts at zero. If pSeed is
930// non-NULL, it uses and updates whatever pSeed points at.
931
932static UInt seed = 0;
933
934UInt VG_(random)( /*MOD*/UInt* pSeed )
njn9828b342005-07-08 04:08:59 +0000935{
sewardj45f4e7c2005-09-27 19:20:21 +0000936 if (pSeed == NULL)
937 pSeed = &seed;
938
939 *pSeed = (1103515245 * *pSeed + 12345);
940 return *pSeed;
njn9828b342005-07-08 04:08:59 +0000941}
942
sewardj5d616df2013-07-02 08:07:15 +0000943
944/* The following Adler-32 checksum code is taken from zlib-1.2.3, which
945 has the following copyright notice. */
946/*
947Copyright notice:
948
949 (C) 1995-2004 Jean-loup Gailly and Mark Adler
950
951 This software is provided 'as-is', without any express or implied
952 warranty. In no event will the authors be held liable for any damages
953 arising from the use of this software.
954
955 Permission is granted to anyone to use this software for any purpose,
956 including commercial applications, and to alter it and redistribute it
957 freely, subject to the following restrictions:
958
959 1. The origin of this software must not be misrepresented; you must not
960 claim that you wrote the original software. If you use this software
961 in a product, an acknowledgment in the product documentation would be
962 appreciated but is not required.
963 2. Altered source versions must be plainly marked as such, and must not be
964 misrepresented as being the original software.
965 3. This notice may not be removed or altered from any source distribution.
966
967 Jean-loup Gailly Mark Adler
968 jloup@gzip.org madler@alumni.caltech.edu
969
970If you use the zlib library in a product, we would appreciate *not*
971receiving lengthy legal documents to sign. The sources are provided
972for free but without warranty of any kind. The library has been
973entirely written by Jean-loup Gailly and Mark Adler; it does not
974include third-party code.
975
976If you redistribute modified sources, we would appreciate that you include
977in the file ChangeLog history information documenting your changes. Please
978read the FAQ for more information on the distribution of modified source
979versions.
980*/
981
982/* Update a running Adler-32 checksum with the bytes buf[0..len-1] and
983 return the updated checksum. If buf is NULL, this function returns
984 the required initial value for the checksum. An Adler-32 checksum is
985 almost as reliable as a CRC32 but can be computed much faster. */
986UInt VG_(adler32)( UInt adler, const UChar* buf, UInt len )
987{
988# define BASE 65521UL /* largest prime smaller than 65536 */
989# define NMAX 5552
990 /* NMAX is the largest n such that
991 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
992
993# define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;}
994# define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
995# define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
996# define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
997# define DO16(buf) DO8(buf,0); DO8(buf,8);
998
999 /* The zlib sources recommend this definition of MOD if the
1000 processor cannot do integer division in hardware. */
1001# define MOD(a) \
1002 do { \
1003 if (a >= (BASE << 16)) a -= (BASE << 16); \
1004 if (a >= (BASE << 15)) a -= (BASE << 15); \
1005 if (a >= (BASE << 14)) a -= (BASE << 14); \
1006 if (a >= (BASE << 13)) a -= (BASE << 13); \
1007 if (a >= (BASE << 12)) a -= (BASE << 12); \
1008 if (a >= (BASE << 11)) a -= (BASE << 11); \
1009 if (a >= (BASE << 10)) a -= (BASE << 10); \
1010 if (a >= (BASE << 9)) a -= (BASE << 9); \
1011 if (a >= (BASE << 8)) a -= (BASE << 8); \
1012 if (a >= (BASE << 7)) a -= (BASE << 7); \
1013 if (a >= (BASE << 6)) a -= (BASE << 6); \
1014 if (a >= (BASE << 5)) a -= (BASE << 5); \
1015 if (a >= (BASE << 4)) a -= (BASE << 4); \
1016 if (a >= (BASE << 3)) a -= (BASE << 3); \
1017 if (a >= (BASE << 2)) a -= (BASE << 2); \
1018 if (a >= (BASE << 1)) a -= (BASE << 1); \
1019 if (a >= BASE) a -= BASE; \
1020 } while (0)
1021# define MOD4(a) \
1022 do { \
1023 if (a >= (BASE << 4)) a -= (BASE << 4); \
1024 if (a >= (BASE << 3)) a -= (BASE << 3); \
1025 if (a >= (BASE << 2)) a -= (BASE << 2); \
1026 if (a >= (BASE << 1)) a -= (BASE << 1); \
1027 if (a >= BASE) a -= BASE; \
1028 } while (0)
1029
1030 UInt sum2;
1031 UInt n;
1032
1033 /* split Adler-32 into component sums */
1034 sum2 = (adler >> 16) & 0xffff;
1035 adler &= 0xffff;
1036
1037 /* in case user likes doing a byte at a time, keep it fast */
1038 if (len == 1) {
1039 adler += buf[0];
1040 if (adler >= BASE)
1041 adler -= BASE;
1042 sum2 += adler;
1043 if (sum2 >= BASE)
1044 sum2 -= BASE;
1045 return adler | (sum2 << 16);
1046 }
1047
1048 /* initial Adler-32 value (deferred check for len == 1 speed) */
1049 if (buf == NULL)
1050 return 1L;
1051
1052 /* in case short lengths are provided, keep it somewhat fast */
1053 if (len < 16) {
1054 while (len--) {
1055 adler += *buf++;
1056 sum2 += adler;
1057 }
1058 if (adler >= BASE)
1059 adler -= BASE;
1060 MOD4(sum2); /* only added so many BASE's */
1061 return adler | (sum2 << 16);
1062 }
1063
1064 /* do length NMAX blocks -- requires just one modulo operation */
1065 while (len >= NMAX) {
1066 len -= NMAX;
1067 n = NMAX / 16; /* NMAX is divisible by 16 */
1068 do {
1069 DO16(buf); /* 16 sums unrolled */
1070 buf += 16;
1071 } while (--n);
1072 MOD(adler);
1073 MOD(sum2);
1074 }
1075
1076 /* do remaining bytes (less than NMAX, still just one modulo) */
1077 if (len) { /* avoid modulos if none remaining */
1078 while (len >= 16) {
1079 len -= 16;
1080 DO16(buf);
1081 buf += 16;
1082 }
1083 while (len--) {
1084 adler += *buf++;
1085 sum2 += adler;
1086 }
1087 MOD(adler);
1088 MOD(sum2);
1089 }
1090
1091 /* return recombined sums */
1092 return adler | (sum2 << 16);
1093
1094# undef MOD4
1095# undef MOD
1096# undef DO16
1097# undef DO8
1098# undef DO4
1099# undef DO2
1100# undef DO1
1101# undef NMAX
1102# undef BASE
1103}
1104
njn97405b22005-06-02 03:39:33 +00001105/*--------------------------------------------------------------------*/
1106/*--- end ---*/
1107/*--------------------------------------------------------------------*/
1108