blob: abacd712d6f9fc2a66c1706f6bc2b32598d81de3 [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
florian6625f712014-07-29 08:46:15 +0000307 SizeT i = 0;
308 while (True) {
309 dest[i] = 0;
310 if (src[i] == 0) return;
311 if (i >= ndest-1) return;
312 dest[i] = src[i];
313 i++;
314 }
njn97405b22005-06-02 03:39:33 +0000315}
316
florian19f91bb2012-11-10 22:29:54 +0000317HChar* VG_(strncpy) ( HChar* dest, const HChar* src, SizeT ndest )
njn97405b22005-06-02 03:39:33 +0000318{
sewardj4f2683a2008-10-26 11:53:30 +0000319 SizeT i = 0;
njn97405b22005-06-02 03:39:33 +0000320 while (True) {
321 if (i >= ndest) return dest; /* reached limit */
322 dest[i] = src[i];
323 if (src[i++] == 0) {
324 /* reached NUL; pad rest with zeroes as required */
325 while (i < ndest) dest[i++] = 0;
326 return dest;
327 }
328 }
329}
330
florian19f91bb2012-11-10 22:29:54 +0000331Int VG_(strcmp) ( const HChar* s1, const HChar* s2 )
njn97405b22005-06-02 03:39:33 +0000332{
333 while (True) {
florian3e798632012-11-24 19:41:54 +0000334 if (*(const UChar*)s1 < *(const UChar*)s2) return -1;
335 if (*(const UChar*)s1 > *(const UChar*)s2) return 1;
njn97405b22005-06-02 03:39:33 +0000336
philippe56ddd5b2012-07-26 22:44:07 +0000337 /* *s1 == *s2 */
338 if (*s1 == 0) return 0;
339
njn97405b22005-06-02 03:39:33 +0000340 s1++; s2++;
341 }
342}
343
florian19f91bb2012-11-10 22:29:54 +0000344Int VG_(strcasecmp) ( const HChar* s1, const HChar* s2 )
njnf76d27a2009-05-28 01:53:07 +0000345{
346 while (True) {
347 UChar c1 = (UChar)VG_(tolower)(*s1);
348 UChar c2 = (UChar)VG_(tolower)(*s2);
njnf76d27a2009-05-28 01:53:07 +0000349 if (c1 < c2) return -1;
350 if (c1 > c2) return 1;
philippe56ddd5b2012-07-26 22:44:07 +0000351
352 /* c1 == c2 */
353 if (c1 == 0) return 0;
njnf76d27a2009-05-28 01:53:07 +0000354
355 s1++; s2++;
356 }
357}
358
florian19f91bb2012-11-10 22:29:54 +0000359Int VG_(strncmp) ( const HChar* s1, const HChar* s2, SizeT nmax )
njn97405b22005-06-02 03:39:33 +0000360{
sewardj4f2683a2008-10-26 11:53:30 +0000361 SizeT n = 0;
njn97405b22005-06-02 03:39:33 +0000362 while (True) {
363 if (n >= nmax) return 0;
florian3e798632012-11-24 19:41:54 +0000364 if (*(const UChar*)s1 < *(const UChar*)s2) return -1;
365 if (*(const UChar*)s1 > *(const UChar*)s2) return 1;
philippe56ddd5b2012-07-26 22:44:07 +0000366
367 /* *s1 == *s2 */
368 if (*s1 == 0) return 0;
njn97405b22005-06-02 03:39:33 +0000369
370 s1++; s2++; n++;
371 }
372}
373
florian19f91bb2012-11-10 22:29:54 +0000374Int VG_(strncasecmp) ( const HChar* s1, const HChar* s2, SizeT nmax )
njnf76d27a2009-05-28 01:53:07 +0000375{
376 Int n = 0;
377 while (True) {
378 UChar c1;
379 UChar c2;
380 if (n >= nmax) return 0;
381 c1 = (UChar)VG_(tolower)(*s1);
382 c2 = (UChar)VG_(tolower)(*s2);
njnf76d27a2009-05-28 01:53:07 +0000383 if (c1 < c2) return -1;
384 if (c1 > c2) return 1;
385
philippe56ddd5b2012-07-26 22:44:07 +0000386 /* c1 == c2 */
387 if (c1 == 0) return 0;
388
njnf76d27a2009-05-28 01:53:07 +0000389 s1++; s2++; n++;
390 }
391}
392
florian19f91bb2012-11-10 22:29:54 +0000393HChar* VG_(strstr) ( const HChar* haystack, const HChar* needle )
njn97405b22005-06-02 03:39:33 +0000394{
sewardj4f2683a2008-10-26 11:53:30 +0000395 SizeT n;
njn97405b22005-06-02 03:39:33 +0000396 if (haystack == NULL)
397 return NULL;
398 n = VG_(strlen)(needle);
399 while (True) {
400 if (haystack[0] == 0)
401 return NULL;
402 if (VG_(strncmp)(haystack, needle, n) == 0)
florian19f91bb2012-11-10 22:29:54 +0000403 return (HChar*)haystack;
njn97405b22005-06-02 03:39:33 +0000404 haystack++;
405 }
406}
407
florian19f91bb2012-11-10 22:29:54 +0000408HChar* VG_(strcasestr) ( const HChar* haystack, const HChar* needle )
njnf76d27a2009-05-28 01:53:07 +0000409{
410 Int n;
411 if (haystack == NULL)
412 return NULL;
413 n = VG_(strlen)(needle);
414 while (True) {
415 if (haystack[0] == 0)
416 return NULL;
417 if (VG_(strncasecmp)(haystack, needle, n) == 0)
florian19f91bb2012-11-10 22:29:54 +0000418 return (HChar*)haystack;
njnf76d27a2009-05-28 01:53:07 +0000419 haystack++;
420 }
421}
422
florian19f91bb2012-11-10 22:29:54 +0000423HChar* VG_(strchr) ( const HChar* s, HChar c )
njn97405b22005-06-02 03:39:33 +0000424{
425 while (True) {
florian19f91bb2012-11-10 22:29:54 +0000426 if (*s == c) return (HChar *)s;
njn97405b22005-06-02 03:39:33 +0000427 if (*s == 0) return NULL;
428 s++;
429 }
430}
431
florian19f91bb2012-11-10 22:29:54 +0000432HChar* VG_(strrchr) ( const HChar* s, HChar c )
njn97405b22005-06-02 03:39:33 +0000433{
434 Int n = VG_(strlen)(s);
435 while (--n > 0) {
florian19f91bb2012-11-10 22:29:54 +0000436 if (s[n] == c) return (HChar *)s + n;
njn97405b22005-06-02 03:39:33 +0000437 }
438 return NULL;
439}
440
sewardj3b290482011-05-06 21:02:55 +0000441/* (code copied from glib then updated to valgrind types) */
florian19f91bb2012-11-10 22:29:54 +0000442static HChar *olds;
443HChar *
444VG_(strtok) (HChar *s, const HChar *delim)
sewardj3b290482011-05-06 21:02:55 +0000445{
446 return VG_(strtok_r) (s, delim, &olds);
447}
448
florian19f91bb2012-11-10 22:29:54 +0000449HChar *
450VG_(strtok_r) (HChar* s, const HChar* delim, HChar** saveptr)
sewardj3b290482011-05-06 21:02:55 +0000451{
florian19f91bb2012-11-10 22:29:54 +0000452 HChar *token;
sewardj3b290482011-05-06 21:02:55 +0000453
454 if (s == NULL)
455 s = *saveptr;
456
457 /* Scan leading delimiters. */
458 s += VG_(strspn (s, delim));
459 if (*s == '\0')
460 {
461 *saveptr = s;
462 return NULL;
463 }
464
465 /* Find the end of the token. */
466 token = s;
467 s = VG_(strpbrk (token, delim));
468 if (s == NULL)
469 /* This token finishes the string. */
470 *saveptr = token + VG_(strlen) (token);
471 else
472 {
473 /* Terminate the token and make OLDS point past it. */
474 *s = '\0';
475 *saveptr = s + 1;
476 }
477 return token;
478}
479
florian19f91bb2012-11-10 22:29:54 +0000480static Bool isHex ( HChar c )
sewardj3b290482011-05-06 21:02:55 +0000481{
482 return ((c >= '0' && c <= '9') ||
483 (c >= 'a' && c <= 'f') ||
484 (c >= 'A' && c <= 'F'));
485}
486
florian19f91bb2012-11-10 22:29:54 +0000487static UInt fromHex ( HChar c )
sewardj3b290482011-05-06 21:02:55 +0000488{
489 if (c >= '0' && c <= '9')
490 return (UInt)c - (UInt)'0';
491 if (c >= 'a' && c <= 'f')
492 return 10 + (UInt)c - (UInt)'a';
493 if (c >= 'A' && c <= 'F')
494 return 10 + (UInt)c - (UInt)'A';
495 /*NOTREACHED*/
496 // ??? need to vg_assert(0);
497 return 0;
498}
499
florian19f91bb2012-11-10 22:29:54 +0000500Bool VG_(parse_Addr) ( const HChar** ppc, Addr* result )
sewardj3b290482011-05-06 21:02:55 +0000501{
502 Int used, limit = 2 * sizeof(Addr);
503 if (**ppc != '0')
504 return False;
505 (*ppc)++;
506 if (**ppc != 'x')
507 return False;
508 (*ppc)++;
509 *result = 0;
510 used = 0;
511 while (isHex(**ppc)) {
512 // ??? need to vg_assert(d < fromHex(**ppc));
513 *result = ((*result) << 4) | fromHex(**ppc);
514 (*ppc)++;
515 used++;
516 if (used > limit) return False;
517 }
518 if (used == 0)
519 return False;
520 return True;
521}
522
philippe0c2923f2014-04-19 09:52:32 +0000523Bool VG_(parse_enum_set) ( const HChar *tokens,
524 const HChar *input,
525 UInt *enum_set)
526{
527 const SizeT tokens_len = VG_(strlen)(tokens);
528 if (tokens_len > 1000) return False; /* "obviously invalid" */
529 HChar tok_tokens[tokens_len+1];
530 HChar *tokens_saveptr;
531 HChar *token;
532 UInt token_nr = 0;
533 UInt all_set = 0;
534
535 const SizeT input_len = VG_(strlen)(input);
536 if (input_len > 1000) return False; /* "obviously invalid" */
537 HChar tok_input[input_len+1];
538 HChar *input_saveptr;
539 HChar *input_word;
540 UInt word_nr = 0;
541 UInt known_words = 0;
542 Bool seen_all_kw = False;
543 Bool seen_none_kw = False;
544
545 *enum_set = 0;
546
547 VG_(strcpy) (tok_input, input);
548 for (input_word = VG_(strtok_r)(tok_input, ",", &input_saveptr);
549 input_word;
550 input_word = VG_(strtok_r)(NULL, ",", &input_saveptr)) {
551 word_nr++;
552 if (0 == VG_(strcmp)(input_word, "all")) {
553 seen_all_kw = True;
554 known_words++;
555 } else if (0 == VG_(strcmp)(input_word, "none")) {
556 seen_none_kw = True;
557 known_words++;
558 }
559
560 // Scan tokens + compute all_set. Do that even if all or none was
561 // recognised to have a correct value for all_set when exiting
562 // of the 'input' loop.
563 all_set = 0;
564 token_nr = 0;
565 VG_(strcpy) (tok_tokens, tokens);
566 for (token = VG_(strtok_r)(tok_tokens, ",", &tokens_saveptr);
567 token;
568 token = VG_(strtok_r)(NULL, ",", &tokens_saveptr)) {
569 if (0 != VG_(strcmp)(token, "-")) {
570 if (0 == VG_(strcmp)(input_word, token)) {
571 *enum_set |= 1 << token_nr;
572 known_words++;
573 }
574 all_set |= 1 << token_nr;
575 }
576 token_nr++;
577 }
578 }
579
580 if (known_words != word_nr)
581 return False; // One or more input_words not recognised.
582 if (seen_all_kw) {
583 if (seen_none_kw || *enum_set)
584 return False; // mixing all with either none or a specific value.
585 *enum_set = all_set;
586 } else if (seen_none_kw) {
587 if (seen_all_kw || *enum_set)
588 return False; // mixing none with either all or a specific value.
589 *enum_set = 0;
590 } else {
591 // seen neither all or none, we must see at least one value
592 if (*enum_set == 0)
593 return False;
594 }
595
596 return True;
597}
598
florian19f91bb2012-11-10 22:29:54 +0000599SizeT VG_(strspn) ( const HChar* s, const HChar* accpt )
sewardj4f2683a2008-10-26 11:53:30 +0000600{
florian19f91bb2012-11-10 22:29:54 +0000601 const HChar *p, *a;
sewardj4f2683a2008-10-26 11:53:30 +0000602 SizeT count = 0;
603 for (p = s; *p != '\0'; ++p) {
njnf9dcb3b2009-05-19 05:50:34 +0000604 for (a = accpt; *a != '\0'; ++a)
sewardj4f2683a2008-10-26 11:53:30 +0000605 if (*p == *a)
606 break;
607 if (*a == '\0')
608 return count;
609 else
610 ++count;
611 }
612 return count;
613}
614
florian19f91bb2012-11-10 22:29:54 +0000615SizeT VG_(strcspn) ( const HChar* s, const HChar* reject )
sewardj4f2683a2008-10-26 11:53:30 +0000616{
617 SizeT count = 0;
618 while (*s != '\0') {
619 if (VG_(strchr) (reject, *s++) == NULL)
620 ++count;
621 else
622 return count;
623 }
624 return count;
625}
626
627
njn97405b22005-06-02 03:39:33 +0000628/* ---------------------------------------------------------------------
njn97405b22005-06-02 03:39:33 +0000629 mem* functions
630 ------------------------------------------------------------------ */
631
632void* VG_(memcpy) ( void *dest, const void *src, SizeT sz )
633{
sewardj45f4e7c2005-09-27 19:20:21 +0000634 const UChar* s = (const UChar*)src;
635 UChar* d = (UChar*)dest;
636 const UInt* sI = (const UInt*)src;
637 UInt* dI = (UInt*)dest;
638
639 if (VG_IS_4_ALIGNED(dI) && VG_IS_4_ALIGNED(sI)) {
640 while (sz >= 16) {
641 dI[0] = sI[0];
642 dI[1] = sI[1];
643 dI[2] = sI[2];
644 dI[3] = sI[3];
645 sz -= 16;
646 dI += 4;
647 sI += 4;
648 }
649 if (sz == 0)
650 return dest;
651 while (sz >= 4) {
652 dI[0] = sI[0];
653 sz -= 4;
654 dI += 1;
655 sI += 1;
656 }
657 if (sz == 0)
658 return dest;
659 s = (const UChar*)sI;
660 d = (UChar*)dI;
661 }
njn97405b22005-06-02 03:39:33 +0000662
sewardj5d616df2013-07-02 08:07:15 +0000663 /* If we're unlucky, the alignment constraints for the fast case
664 above won't apply, and we'll have to to it all here. Hence the
665 unrolling. */
666 while (sz >= 4) {
667 d[0] = s[0];
668 d[1] = s[1];
669 d[2] = s[2];
670 d[3] = s[3];
671 d += 4;
672 s += 4;
673 sz -= 4;
674 }
675 while (sz >= 1) {
676 d[0] = s[0];
677 d += 1;
678 s += 1;
679 sz -= 1;
680 }
njn97405b22005-06-02 03:39:33 +0000681
682 return dest;
683}
684
sewardjbbec7722007-11-25 14:08:53 +0000685void* VG_(memmove)(void *dest, const void *src, SizeT sz)
686{
687 SizeT i;
688 if (sz == 0)
689 return dest;
690 if (dest < src) {
691 for (i = 0; i < sz; i++) {
florian3e798632012-11-24 19:41:54 +0000692 ((UChar*)dest)[i] = ((const UChar*)src)[i];
sewardjbbec7722007-11-25 14:08:53 +0000693 }
694 }
695 else if (dest > src) {
tom4634b012009-11-03 21:14:31 +0000696 for (i = 0; i < sz; i++) {
florian3e798632012-11-24 19:41:54 +0000697 ((UChar*)dest)[sz-i-1] = ((const UChar*)src)[sz-i-1];
sewardjbbec7722007-11-25 14:08:53 +0000698 }
699 }
700 return dest;
701}
702
sewardjb8b79ad2008-03-03 01:35:41 +0000703void* VG_(memset) ( void *destV, Int c, SizeT sz )
njn97405b22005-06-02 03:39:33 +0000704{
sewardjb8b79ad2008-03-03 01:35:41 +0000705 Int c4;
florian19f91bb2012-11-10 22:29:54 +0000706 HChar* d = (HChar*)destV;
sewardjb8b79ad2008-03-03 01:35:41 +0000707 while ((!VG_IS_4_ALIGNED(d)) && sz >= 1) {
sewardj3187a4e2005-12-04 23:27:14 +0000708 d[0] = c;
709 d++;
710 sz--;
711 }
sewardjb8b79ad2008-03-03 01:35:41 +0000712 if (sz == 0)
713 return destV;
714 c4 = c & 0xFF;
715 c4 |= (c4 << 8);
716 c4 |= (c4 << 16);
717 while (sz >= 16) {
718 ((Int*)d)[0] = c4;
719 ((Int*)d)[1] = c4;
720 ((Int*)d)[2] = c4;
721 ((Int*)d)[3] = c4;
722 d += 16;
723 sz -= 16;
724 }
725 while (sz >= 4) {
726 ((Int*)d)[0] = c4;
727 d += 4;
728 sz -= 4;
729 }
730 while (sz >= 1) {
731 d[0] = c;
732 d++;
733 sz--;
734 }
735 return destV;
njn97405b22005-06-02 03:39:33 +0000736}
737
738Int VG_(memcmp) ( const void* s1, const void* s2, SizeT n )
739{
740 Int res;
tom151a6392005-11-11 12:30:36 +0000741 const UChar *p1 = s1;
742 const UChar *p2 = s2;
njn97405b22005-06-02 03:39:33 +0000743 UChar a0;
744 UChar b0;
745
746 while (n != 0) {
tom151a6392005-11-11 12:30:36 +0000747 a0 = p1[0];
748 b0 = p2[0];
749 p1 += 1;
750 p2 += 1;
njn97405b22005-06-02 03:39:33 +0000751 res = a0 - b0;
752 if (res != 0)
753 return res;
754 n -= 1;
755 }
756 return 0;
757}
758
759/* ---------------------------------------------------------------------
760 Misc useful functions
761 ------------------------------------------------------------------ */
762
sewardjb8b79ad2008-03-03 01:35:41 +0000763/////////////////////////////////////////////////////////////
764/////////////////////////////////////////////////////////////
765/// begin Bentley-McIlroy style quicksort
766/// See "Engineering a Sort Function". Jon L Bentley, M. Douglas
767/// McIlroy. Software Practice and Experience Vol 23(11), Nov 1993.
768
769#define BM_MIN(a, b) \
770 (a) < (b) ? a : b
771
772#define BM_SWAPINIT(a, es) \
773 swaptype = ((a-(Char*)0) | es) % sizeof(Word) ? 2 \
774 : es > (SizeT)sizeof(Word) ? 1 \
775 : 0
776
777#define BM_EXCH(a, b, t) \
778 (t = a, a = b, b = t)
779
780#define BM_SWAP(a, b) \
781 swaptype != 0 \
782 ? bm_swapfunc(a, b, es, swaptype) \
783 : (void)BM_EXCH(*(Word*)(a), *(Word*)(b), t)
784
785#define BM_VECSWAP(a, b, n) \
786 if (n > 0) bm_swapfunc(a, b, n, swaptype)
787
788#define BM_PVINIT(pv, pm) \
789 if (swaptype != 0) \
790 pv = a, BM_SWAP(pv, pm); \
791 else \
792 pv = (Char*)&v, v = *(Word*)pm
793
794static Char* bm_med3 ( Char* a, Char* b, Char* c,
florian6bd9dc12012-11-23 16:17:43 +0000795 Int (*cmp)(const void*, const void*) ) {
sewardjb8b79ad2008-03-03 01:35:41 +0000796 return cmp(a, b) < 0
797 ? (cmp(b, c) < 0 ? b : cmp(a, c) < 0 ? c : a)
798 : (cmp(b, c) > 0 ? b : cmp(a, c) > 0 ? c : a);
799}
800
801static void bm_swapfunc ( Char* a, Char* b, SizeT n, Int swaptype )
802{
803 if (swaptype <= 1) {
804 Word t;
805 for ( ; n > 0; a += sizeof(Word), b += sizeof(Word),
806 n -= sizeof(Word))
807 BM_EXCH(*(Word*)a, *(Word*)b, t);
808 } else {
809 Char t;
810 for ( ; n > 0; a += 1, b += 1, n -= 1)
811 BM_EXCH(*a, *b, t);
812 }
813}
814
815static void bm_qsort ( Char* a, SizeT n, SizeT es,
florian6bd9dc12012-11-23 16:17:43 +0000816 Int (*cmp)(const void*, const void*) )
sewardjb8b79ad2008-03-03 01:35:41 +0000817{
818 Char *pa, *pb, *pc, *pd, *pl, *pm, *pn, *pv;
819 Int r, swaptype;
820 Word t, v;
821 SizeT s, s1, s2;
822 tailcall:
823 BM_SWAPINIT(a, es);
824 if (n < 7) {
825 for (pm = a + es; pm < a + n*es; pm += es)
826 for (pl = pm; pl > a && cmp(pl-es, pl) > 0; pl -= es)
827 BM_SWAP(pl, pl-es);
828 return;
829 }
830 pm = a + (n/2)*es;
831 if (n > 7) {
832 pl = a;
833 pn = a + (n-1)*es;
834 if (n > 40) {
835 s = (n/8)*es;
836 pl = bm_med3(pl, pl+s, pl+2*s, cmp);
837 pm = bm_med3(pm-s, pm, pm+s, cmp);
838 pn = bm_med3(pn-2*s, pn-s, pn, cmp);
839 }
840 pm = bm_med3(pl, pm, pn, cmp);
841 }
842 BM_PVINIT(pv, pm);
843 pa = pb = a;
844 pc = pd = a + (n-1)*es;
845 for (;;) {
846 while (pb <= pc && (r = cmp(pb, pv)) <= 0) {
847 if (r == 0) { BM_SWAP(pa, pb); pa += es; }
848 pb += es;
849 }
850 while (pc >= pb && (r = cmp(pc, pv)) >= 0) {
851 if (r == 0) { BM_SWAP(pc, pd); pd -= es; }
852 pc -= es;
853 }
854 if (pb > pc) break;
855 BM_SWAP(pb, pc);
856 pb += es;
857 pc -= es;
858 }
859 pn = a + n*es;
860 s = BM_MIN(pa-a, pb-pa ); BM_VECSWAP(a, pb-s, s);
861 s = BM_MIN(pd-pc, pn-pd-es); BM_VECSWAP(pb, pn-s, s);
862 /* Now recurse. Do the smaller partition first with an explicit
863 recursion, then do the larger partition using a tail call.
864 Except we can't rely on gcc to implement a tail call in any sane
865 way, so simply jump back to the start. This guarantees stack
866 growth can never exceed O(log N) even in the worst case. */
867 s1 = pb-pa;
868 s2 = pd-pc;
869 if (s1 < s2) {
870 if (s1 > es) {
871 bm_qsort(a, s1/es, es, cmp);
872 }
873 if (s2 > es) {
874 /* bm_qsort(pn-s2, s2/es, es, cmp); */
875 a = pn-s2; n = s2/es; es = es; cmp = cmp;
876 goto tailcall;
877 }
878 } else {
879 if (s2 > es) {
880 bm_qsort(pn-s2, s2/es, es, cmp);
881 }
882 if (s1 > es) {
883 /* bm_qsort(a, s1/es, es, cmp); */
884 a = a; n = s1/es; es = es; cmp = cmp;
885 goto tailcall;
886 }
887 }
888}
889
890#undef BM_MIN
891#undef BM_SWAPINIT
892#undef BM_EXCH
893#undef BM_SWAP
894#undef BM_VECSWAP
895#undef BM_PVINIT
896
897/// end Bentley-McIlroy style quicksort
898/////////////////////////////////////////////////////////////
899/////////////////////////////////////////////////////////////
900
901/* Returns the base-2 logarithm of x. Returns -1 if x is not a power
902 of two. */
903Int VG_(log2) ( UInt x )
njn97405b22005-06-02 03:39:33 +0000904{
905 Int i;
906 /* Any more than 32 and we overflow anyway... */
907 for (i = 0; i < 32; i++) {
sewardjb8b79ad2008-03-03 01:35:41 +0000908 if ((1U << i) == x) return i;
njn97405b22005-06-02 03:39:33 +0000909 }
910 return -1;
911}
912
sewardjaebbf1c2011-06-13 13:14:00 +0000913/* Ditto for 64 bit numbers. */
914Int VG_(log2_64) ( ULong x )
915{
916 Int i;
917 for (i = 0; i < 64; i++) {
918 if ((1ULL << i) == x) return i;
919 }
920 return -1;
921}
njn97405b22005-06-02 03:39:33 +0000922
njnfab29902008-03-03 02:15:03 +0000923// Generic quick sort.
njn97405b22005-06-02 03:39:33 +0000924void VG_(ssort)( void* base, SizeT nmemb, SizeT size,
florian6bd9dc12012-11-23 16:17:43 +0000925 Int (*compar)(const void*, const void*) )
njn97405b22005-06-02 03:39:33 +0000926{
sewardjb8b79ad2008-03-03 01:35:41 +0000927 bm_qsort(base,nmemb,size,compar);
njn97405b22005-06-02 03:39:33 +0000928}
929
sewardjb8b79ad2008-03-03 01:35:41 +0000930
njn9828b342005-07-08 04:08:59 +0000931// This random number generator is based on the one suggested in Kernighan
932// and Ritchie's "The C Programming Language".
sewardj45f4e7c2005-09-27 19:20:21 +0000933
934// A pseudo-random number generator returning a random UInt. If pSeed
935// is NULL, it uses its own seed, which starts at zero. If pSeed is
936// non-NULL, it uses and updates whatever pSeed points at.
937
938static UInt seed = 0;
939
940UInt VG_(random)( /*MOD*/UInt* pSeed )
njn9828b342005-07-08 04:08:59 +0000941{
sewardj45f4e7c2005-09-27 19:20:21 +0000942 if (pSeed == NULL)
943 pSeed = &seed;
944
945 *pSeed = (1103515245 * *pSeed + 12345);
946 return *pSeed;
njn9828b342005-07-08 04:08:59 +0000947}
948
sewardj5d616df2013-07-02 08:07:15 +0000949
950/* The following Adler-32 checksum code is taken from zlib-1.2.3, which
951 has the following copyright notice. */
952/*
953Copyright notice:
954
955 (C) 1995-2004 Jean-loup Gailly and Mark Adler
956
957 This software is provided 'as-is', without any express or implied
958 warranty. In no event will the authors be held liable for any damages
959 arising from the use of this software.
960
961 Permission is granted to anyone to use this software for any purpose,
962 including commercial applications, and to alter it and redistribute it
963 freely, subject to the following restrictions:
964
965 1. The origin of this software must not be misrepresented; you must not
966 claim that you wrote the original software. If you use this software
967 in a product, an acknowledgment in the product documentation would be
968 appreciated but is not required.
969 2. Altered source versions must be plainly marked as such, and must not be
970 misrepresented as being the original software.
971 3. This notice may not be removed or altered from any source distribution.
972
973 Jean-loup Gailly Mark Adler
974 jloup@gzip.org madler@alumni.caltech.edu
975
976If you use the zlib library in a product, we would appreciate *not*
977receiving lengthy legal documents to sign. The sources are provided
978for free but without warranty of any kind. The library has been
979entirely written by Jean-loup Gailly and Mark Adler; it does not
980include third-party code.
981
982If you redistribute modified sources, we would appreciate that you include
983in the file ChangeLog history information documenting your changes. Please
984read the FAQ for more information on the distribution of modified source
985versions.
986*/
987
988/* Update a running Adler-32 checksum with the bytes buf[0..len-1] and
989 return the updated checksum. If buf is NULL, this function returns
990 the required initial value for the checksum. An Adler-32 checksum is
991 almost as reliable as a CRC32 but can be computed much faster. */
992UInt VG_(adler32)( UInt adler, const UChar* buf, UInt len )
993{
994# define BASE 65521UL /* largest prime smaller than 65536 */
995# define NMAX 5552
996 /* NMAX is the largest n such that
997 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
998
999# define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;}
1000# define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
1001# define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
1002# define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
1003# define DO16(buf) DO8(buf,0); DO8(buf,8);
1004
1005 /* The zlib sources recommend this definition of MOD if the
1006 processor cannot do integer division in hardware. */
1007# define MOD(a) \
1008 do { \
1009 if (a >= (BASE << 16)) a -= (BASE << 16); \
1010 if (a >= (BASE << 15)) a -= (BASE << 15); \
1011 if (a >= (BASE << 14)) a -= (BASE << 14); \
1012 if (a >= (BASE << 13)) a -= (BASE << 13); \
1013 if (a >= (BASE << 12)) a -= (BASE << 12); \
1014 if (a >= (BASE << 11)) a -= (BASE << 11); \
1015 if (a >= (BASE << 10)) a -= (BASE << 10); \
1016 if (a >= (BASE << 9)) a -= (BASE << 9); \
1017 if (a >= (BASE << 8)) a -= (BASE << 8); \
1018 if (a >= (BASE << 7)) a -= (BASE << 7); \
1019 if (a >= (BASE << 6)) a -= (BASE << 6); \
1020 if (a >= (BASE << 5)) a -= (BASE << 5); \
1021 if (a >= (BASE << 4)) a -= (BASE << 4); \
1022 if (a >= (BASE << 3)) a -= (BASE << 3); \
1023 if (a >= (BASE << 2)) a -= (BASE << 2); \
1024 if (a >= (BASE << 1)) a -= (BASE << 1); \
1025 if (a >= BASE) a -= BASE; \
1026 } while (0)
1027# define MOD4(a) \
1028 do { \
1029 if (a >= (BASE << 4)) a -= (BASE << 4); \
1030 if (a >= (BASE << 3)) a -= (BASE << 3); \
1031 if (a >= (BASE << 2)) a -= (BASE << 2); \
1032 if (a >= (BASE << 1)) a -= (BASE << 1); \
1033 if (a >= BASE) a -= BASE; \
1034 } while (0)
1035
1036 UInt sum2;
1037 UInt n;
1038
1039 /* split Adler-32 into component sums */
1040 sum2 = (adler >> 16) & 0xffff;
1041 adler &= 0xffff;
1042
1043 /* in case user likes doing a byte at a time, keep it fast */
1044 if (len == 1) {
1045 adler += buf[0];
1046 if (adler >= BASE)
1047 adler -= BASE;
1048 sum2 += adler;
1049 if (sum2 >= BASE)
1050 sum2 -= BASE;
1051 return adler | (sum2 << 16);
1052 }
1053
1054 /* initial Adler-32 value (deferred check for len == 1 speed) */
1055 if (buf == NULL)
1056 return 1L;
1057
1058 /* in case short lengths are provided, keep it somewhat fast */
1059 if (len < 16) {
1060 while (len--) {
1061 adler += *buf++;
1062 sum2 += adler;
1063 }
1064 if (adler >= BASE)
1065 adler -= BASE;
1066 MOD4(sum2); /* only added so many BASE's */
1067 return adler | (sum2 << 16);
1068 }
1069
1070 /* do length NMAX blocks -- requires just one modulo operation */
1071 while (len >= NMAX) {
1072 len -= NMAX;
1073 n = NMAX / 16; /* NMAX is divisible by 16 */
1074 do {
1075 DO16(buf); /* 16 sums unrolled */
1076 buf += 16;
1077 } while (--n);
1078 MOD(adler);
1079 MOD(sum2);
1080 }
1081
1082 /* do remaining bytes (less than NMAX, still just one modulo) */
1083 if (len) { /* avoid modulos if none remaining */
1084 while (len >= 16) {
1085 len -= 16;
1086 DO16(buf);
1087 buf += 16;
1088 }
1089 while (len--) {
1090 adler += *buf++;
1091 sum2 += adler;
1092 }
1093 MOD(adler);
1094 MOD(sum2);
1095 }
1096
1097 /* return recombined sums */
1098 return adler | (sum2 << 16);
1099
1100# undef MOD4
1101# undef MOD
1102# undef DO16
1103# undef DO8
1104# undef DO4
1105# undef DO2
1106# undef DO1
1107# undef NMAX
1108# undef BASE
1109}
1110
njn97405b22005-06-02 03:39:33 +00001111/*--------------------------------------------------------------------*/
1112/*--- end ---*/
1113/*--------------------------------------------------------------------*/
1114