1// This module does unit testing of m_libcbase.
2
3#include <assert.h>
4#include <stdio.h>
5#include <stdlib.h>
6
7#include "pub_tool_basics.h"  /* UInt et al, needed for pub_tool_vki.h */
8#include "pub_tool_vki.h"
9#include "m_libcbase.c"
10
11#define  CHECK(x) \
12   if (!x) { fprintf(stderr, "failure: %s:%d\n", __FILE__, __LINE__); }
13
14
15void test_VG_STREQ(void)
16{
17   CHECK( ! VG_STREQ(NULL,    NULL) );  // Nb: strcmp() considers these equal
18   CHECK( ! VG_STREQ(NULL,    "ab") );  // Nb: strcmp() seg faults on this
19   CHECK( ! VG_STREQ("ab",    NULL) );  // Nb: strcmp() seg faults on this
20   CHECK( ! VG_STREQ("",      "a")  );
21   CHECK( ! VG_STREQ("a",     "")   );
22   CHECK( ! VG_STREQ("abc",   "abcd"));
23   CHECK( ! VG_STREQ("abcd",  "abc") );
24   CHECK( ! VG_STREQ("Abcd",  "abcd"));
25   CHECK( ! VG_STREQ("abcd",  "Abcd"));
26
27   CHECK( VG_STREQ("",     "") );
28   CHECK( VG_STREQ("a",    "a") );
29   CHECK( VG_STREQ("abcd", "abcd") );
30}
31
32void test_VG_STREQN(void)
33{
34   CHECK( ! VG_STREQN(0, NULL,    NULL) );
35   CHECK( ! VG_STREQN(5, NULL,    NULL) );
36   CHECK( ! VG_STREQN(0, NULL,    "ab") );
37   CHECK( ! VG_STREQN(5, NULL,    "ab") );
38   CHECK( ! VG_STREQN(0, "ab",    NULL) );
39   CHECK( ! VG_STREQN(1, "",      "a")  );
40   CHECK( ! VG_STREQN(1, "a",     "")   );
41   CHECK( ! VG_STREQN(4, "abc",   "abcd"));
42   CHECK( ! VG_STREQN(4, "abcd",  "abc") );
43   CHECK( ! VG_STREQN(1, "Abcd",  "abcd"));
44   CHECK( ! VG_STREQN(4, "Abcd",  "abcd"));
45   CHECK( ! VG_STREQN(4, "abcd",  "abce"));
46   CHECK( ! VG_STREQN(9, "abcd",  "abce"));
47
48   CHECK( VG_STREQN(0, "",     "") );
49   CHECK( VG_STREQN(1, "",     "") );
50   CHECK( VG_STREQN(0, "a",    "a") );
51   CHECK( VG_STREQN(1, "a",    "a") );
52   CHECK( VG_STREQN(2, "a",    "a") );
53   CHECK( VG_STREQN(9, "a",    "a") );
54   CHECK( VG_STREQN(1, "ab",   "ac"));
55   CHECK( VG_STREQN(3, "abcd", "abce"));
56}
57
58// On PPC/Linux VKI_PAGE_SIZE is a variable, not a macro.
59#if defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
60unsigned long VKI_PAGE_SIZE  = 1UL << 12;
61#elif defined(VGP_arm64_linux)
62unsigned long VKI_PAGE_SIZE  = 1UL << 16;
63#endif
64
65void test_VG_IS_XYZ_ALIGNED(void)
66{
67   CHECK(   VG_IS_2_ALIGNED(0x0) );
68   CHECK( ! VG_IS_2_ALIGNED(0x1) );
69   CHECK(   VG_IS_2_ALIGNED(0x2) );
70   CHECK( ! VG_IS_2_ALIGNED(0x3) );
71   CHECK(   VG_IS_2_ALIGNED(0x4) );
72   CHECK( ! VG_IS_2_ALIGNED(0x5) );
73   CHECK(   VG_IS_2_ALIGNED(0x6) );
74   CHECK( ! VG_IS_2_ALIGNED(0x7) );
75   CHECK(   VG_IS_2_ALIGNED(0x8) );
76   CHECK( ! VG_IS_2_ALIGNED(0x9) );
77   CHECK(   VG_IS_2_ALIGNED(0xa) );
78   CHECK( ! VG_IS_2_ALIGNED(0xb) );
79   CHECK(   VG_IS_2_ALIGNED(0xc) );
80   CHECK( ! VG_IS_2_ALIGNED(0xd) );
81   CHECK(   VG_IS_2_ALIGNED(0xe) );
82   CHECK( ! VG_IS_2_ALIGNED(0xf) );
83
84   CHECK(   VG_IS_4_ALIGNED(0x0) );
85   CHECK( ! VG_IS_4_ALIGNED(0x1) );
86   CHECK( ! VG_IS_4_ALIGNED(0x2) );
87   CHECK( ! VG_IS_4_ALIGNED(0x3) );
88   CHECK(   VG_IS_4_ALIGNED(0x4) );
89   CHECK( ! VG_IS_4_ALIGNED(0x5) );
90   CHECK( ! VG_IS_4_ALIGNED(0x6) );
91   CHECK( ! VG_IS_4_ALIGNED(0x7) );
92   CHECK(   VG_IS_4_ALIGNED(0x8) );
93   CHECK( ! VG_IS_4_ALIGNED(0x9) );
94   CHECK( ! VG_IS_4_ALIGNED(0xa) );
95   CHECK( ! VG_IS_4_ALIGNED(0xb) );
96   CHECK(   VG_IS_4_ALIGNED(0xc) );
97   CHECK( ! VG_IS_4_ALIGNED(0xd) );
98   CHECK( ! VG_IS_4_ALIGNED(0xe) );
99   CHECK( ! VG_IS_4_ALIGNED(0xf) );
100
101   CHECK(   VG_IS_8_ALIGNED(0x0) );
102   CHECK( ! VG_IS_8_ALIGNED(0x1) );
103   CHECK( ! VG_IS_8_ALIGNED(0x2) );
104   CHECK( ! VG_IS_8_ALIGNED(0x3) );
105   CHECK( ! VG_IS_8_ALIGNED(0x4) );
106   CHECK( ! VG_IS_8_ALIGNED(0x5) );
107   CHECK( ! VG_IS_8_ALIGNED(0x6) );
108   CHECK( ! VG_IS_8_ALIGNED(0x7) );
109   CHECK(   VG_IS_8_ALIGNED(0x8) );
110   CHECK( ! VG_IS_8_ALIGNED(0x9) );
111   CHECK( ! VG_IS_8_ALIGNED(0xa) );
112   CHECK( ! VG_IS_8_ALIGNED(0xb) );
113   CHECK( ! VG_IS_8_ALIGNED(0xc) );
114   CHECK( ! VG_IS_8_ALIGNED(0xd) );
115   CHECK( ! VG_IS_8_ALIGNED(0xe) );
116   CHECK( ! VG_IS_8_ALIGNED(0xf) );
117
118   CHECK(   VG_IS_16_ALIGNED(0x0) );
119   CHECK( ! VG_IS_16_ALIGNED(0x1) );
120   CHECK( ! VG_IS_16_ALIGNED(0x2) );
121   CHECK( ! VG_IS_16_ALIGNED(0x3) );
122   CHECK( ! VG_IS_16_ALIGNED(0x4) );
123   CHECK( ! VG_IS_16_ALIGNED(0x5) );
124   CHECK( ! VG_IS_16_ALIGNED(0x6) );
125   CHECK( ! VG_IS_16_ALIGNED(0x7) );
126   CHECK( ! VG_IS_16_ALIGNED(0x8) );
127   CHECK( ! VG_IS_16_ALIGNED(0x9) );
128   CHECK( ! VG_IS_16_ALIGNED(0xa) );
129   CHECK( ! VG_IS_16_ALIGNED(0xb) );
130   CHECK( ! VG_IS_16_ALIGNED(0xc) );
131   CHECK( ! VG_IS_16_ALIGNED(0xd) );
132   CHECK( ! VG_IS_16_ALIGNED(0xe) );
133   CHECK( ! VG_IS_16_ALIGNED(0xf) );
134
135   CHECK(   VG_IS_WORD_ALIGNED(0x0) );
136   CHECK( ! VG_IS_WORD_ALIGNED(0x1) );
137   CHECK( ! VG_IS_WORD_ALIGNED(0x2) );
138   CHECK( ! VG_IS_WORD_ALIGNED(0x3) );
139   // 0x4 case below
140   CHECK( ! VG_IS_WORD_ALIGNED(0x5) );
141   CHECK( ! VG_IS_WORD_ALIGNED(0x6) );
142   CHECK( ! VG_IS_WORD_ALIGNED(0x7) );
143   CHECK(   VG_IS_WORD_ALIGNED(0x8) );
144   CHECK( ! VG_IS_WORD_ALIGNED(0x9) );
145   CHECK( ! VG_IS_WORD_ALIGNED(0xa) );
146   CHECK( ! VG_IS_WORD_ALIGNED(0xb) );
147   // 0xc case below
148   CHECK( ! VG_IS_WORD_ALIGNED(0xd) );
149   CHECK( ! VG_IS_WORD_ALIGNED(0xe) );
150   CHECK( ! VG_IS_WORD_ALIGNED(0xf) );
151   if        (4 == sizeof(void*)) {
152      CHECK(   VG_IS_WORD_ALIGNED(0x4) );
153      CHECK(   VG_IS_WORD_ALIGNED(0xc) );
154   } else if (8 == sizeof(void*)) {
155      CHECK( ! VG_IS_WORD_ALIGNED(0x4) );
156      CHECK( ! VG_IS_WORD_ALIGNED(0xc) );
157   } else {
158      assert(0);
159   }
160
161   CHECK(   VG_IS_PAGE_ALIGNED(0x0) );
162   CHECK( ! VG_IS_PAGE_ALIGNED(0x1) );
163   CHECK( ! VG_IS_PAGE_ALIGNED(0x2) );
164   CHECK( ! VG_IS_PAGE_ALIGNED(0x3) );
165   CHECK( ! VG_IS_PAGE_ALIGNED(0x4) );
166   CHECK( ! VG_IS_PAGE_ALIGNED(VKI_PAGE_SIZE-1) );
167   CHECK(   VG_IS_PAGE_ALIGNED(VKI_PAGE_SIZE  ) );
168   CHECK( ! VG_IS_PAGE_ALIGNED(VKI_PAGE_SIZE+1) );
169}
170
171void test_VG_ROUND_et_al()
172{
173   CHECK( 0 == VG_ROUNDDN(0, 1) );
174   CHECK( 1 == VG_ROUNDDN(1, 1) );
175   CHECK( 2 == VG_ROUNDDN(2, 1) );
176   CHECK( 3 == VG_ROUNDDN(3, 1) );
177   CHECK( 4 == VG_ROUNDDN(4, 1) );
178   CHECK( 5 == VG_ROUNDDN(5, 1) );
179   CHECK( 6 == VG_ROUNDDN(6, 1) );
180   CHECK( 7 == VG_ROUNDDN(7, 1) );
181
182   CHECK( 0 == VG_ROUNDUP(0, 1) );
183   CHECK( 1 == VG_ROUNDUP(1, 1) );
184   CHECK( 2 == VG_ROUNDUP(2, 1) );
185   CHECK( 3 == VG_ROUNDUP(3, 1) );
186   CHECK( 4 == VG_ROUNDUP(4, 1) );
187   CHECK( 5 == VG_ROUNDUP(5, 1) );
188   CHECK( 6 == VG_ROUNDUP(6, 1) );
189   CHECK( 7 == VG_ROUNDUP(7, 1) );
190
191   CHECK( 0 == VG_ROUNDDN(0, 2) );
192   CHECK( 0 == VG_ROUNDDN(1, 2) );
193   CHECK( 2 == VG_ROUNDDN(2, 2) );
194   CHECK( 2 == VG_ROUNDDN(3, 2) );
195   CHECK( 4 == VG_ROUNDDN(4, 2) );
196   CHECK( 4 == VG_ROUNDDN(5, 2) );
197   CHECK( 6 == VG_ROUNDDN(6, 2) );
198   CHECK( 6 == VG_ROUNDDN(7, 2) );
199
200   CHECK( 0 == VG_ROUNDUP(0, 2) );
201   CHECK( 2 == VG_ROUNDUP(1, 2) );
202   CHECK( 2 == VG_ROUNDUP(2, 2) );
203   CHECK( 4 == VG_ROUNDUP(3, 2) );
204   CHECK( 4 == VG_ROUNDUP(4, 2) );
205   CHECK( 6 == VG_ROUNDUP(5, 2) );
206   CHECK( 6 == VG_ROUNDUP(6, 2) );
207   CHECK( 8 == VG_ROUNDUP(7, 2) );
208
209   CHECK( 0 == VG_ROUNDDN(0, 4) );
210   CHECK( 0 == VG_ROUNDDN(1, 4) );
211   CHECK( 0 == VG_ROUNDDN(2, 4) );
212   CHECK( 0 == VG_ROUNDDN(3, 4) );
213   CHECK( 4 == VG_ROUNDDN(4, 4) );
214   CHECK( 4 == VG_ROUNDDN(5, 4) );
215   CHECK( 4 == VG_ROUNDDN(6, 4) );
216   CHECK( 4 == VG_ROUNDDN(7, 4) );
217
218   CHECK( 0 == VG_ROUNDUP(0, 4) );
219   CHECK( 4 == VG_ROUNDUP(1, 4) );
220   CHECK( 4 == VG_ROUNDUP(2, 4) );
221   CHECK( 4 == VG_ROUNDUP(3, 4) );
222   CHECK( 4 == VG_ROUNDUP(4, 4) );
223   CHECK( 8 == VG_ROUNDUP(5, 4) );
224   CHECK( 8 == VG_ROUNDUP(6, 4) );
225   CHECK( 8 == VG_ROUNDUP(7, 4) );
226
227   CHECK( 0 == VG_ROUNDDN(0, 8) );
228   CHECK( 0 == VG_ROUNDDN(1, 8) );
229   CHECK( 0 == VG_ROUNDDN(2, 8) );
230   CHECK( 0 == VG_ROUNDDN(3, 8) );
231   CHECK( 0 == VG_ROUNDDN(4, 8) );
232   CHECK( 0 == VG_ROUNDDN(5, 8) );
233   CHECK( 0 == VG_ROUNDDN(6, 8) );
234   CHECK( 0 == VG_ROUNDDN(7, 8) );
235
236   CHECK( 0 == VG_ROUNDUP(0, 8) );
237   CHECK( 8 == VG_ROUNDUP(1, 8) );
238   CHECK( 8 == VG_ROUNDUP(2, 8) );
239   CHECK( 8 == VG_ROUNDUP(3, 8) );
240   CHECK( 8 == VG_ROUNDUP(4, 8) );
241   CHECK( 8 == VG_ROUNDUP(5, 8) );
242   CHECK( 8 == VG_ROUNDUP(6, 8) );
243   CHECK( 8 == VG_ROUNDUP(7, 8) );
244
245   CHECK( 0             == VG_PGROUNDDN(0) );
246   CHECK( 0             == VG_PGROUNDDN(1) );
247   CHECK( 0             == VG_PGROUNDDN(2) );
248   CHECK( 0             == VG_PGROUNDDN(3) );
249   CHECK( 0             == VG_PGROUNDDN(4) );
250   CHECK( 0             == VG_PGROUNDDN(VKI_PAGE_SIZE-1) );
251   CHECK( VKI_PAGE_SIZE == VG_PGROUNDDN(VKI_PAGE_SIZE  ) );
252   CHECK( VKI_PAGE_SIZE == VG_PGROUNDDN(VKI_PAGE_SIZE+1) );
253
254   CHECK( 0               == VG_PGROUNDUP(0) );
255   CHECK( VKI_PAGE_SIZE   == VG_PGROUNDUP(1) );
256   CHECK( VKI_PAGE_SIZE   == VG_PGROUNDUP(2) );
257   CHECK( VKI_PAGE_SIZE   == VG_PGROUNDUP(3) );
258   CHECK( VKI_PAGE_SIZE   == VG_PGROUNDUP(4) );
259   CHECK( VKI_PAGE_SIZE   == VG_PGROUNDUP(VKI_PAGE_SIZE-1) );
260   CHECK( VKI_PAGE_SIZE   == VG_PGROUNDUP(VKI_PAGE_SIZE  ) );
261   CHECK( VKI_PAGE_SIZE*2 == VG_PGROUNDUP(VKI_PAGE_SIZE+1) );
262}
263
264void test_isspace(void)
265{
266   CHECK(   VG_(isspace)(' ') );
267   CHECK(   VG_(isspace)('\n') );
268   CHECK(   VG_(isspace)('\t') );
269   CHECK( ! VG_(isspace)('3') );
270   CHECK( ! VG_(isspace)('x') );
271}
272
273void test_isdigit(void)
274{
275   CHECK(   VG_(isdigit)('0') );
276   CHECK(   VG_(isdigit)('1') );
277   CHECK(   VG_(isdigit)('5') );
278   CHECK(   VG_(isdigit)('9') );
279   CHECK( ! VG_(isdigit)('a') );
280   CHECK( ! VG_(isdigit)('!') );
281}
282
283void test_is_dec_digit()
284{
285   Long x;
286   CHECK( is_dec_digit('0', &x) && 0 == x );
287   CHECK( is_dec_digit('1', &x) && 1 == x );
288   CHECK( is_dec_digit('9', &x) && 9 == x );
289}
290
291void test_is_hex_digit()
292{
293   Long x;
294   CHECK( is_hex_digit('0', &x) &&  0 == x );
295   CHECK( is_hex_digit('1', &x) &&  1 == x );
296   CHECK( is_hex_digit('9', &x) &&  9 == x );
297   CHECK( is_hex_digit('a', &x) && 10 == x );
298   CHECK( is_hex_digit('f', &x) && 15 == x );
299   CHECK( is_hex_digit('A', &x) && 10 == x );
300   CHECK( is_hex_digit('F', &x) && 15 == x );
301}
302
303void test_strtoll_and_strtod(void)
304{
305   // For VG_(strtoll*)()
306   typedef struct {
307      HChar* str;        // The string to convert.
308      Long   res;        // The result.
309      HChar  endptr_val; // The char one past the end of the converted text.
310   } StrtollInputs;
311
312   // VG_(strtoll10)()
313   {
314      StrtollInputs a[] = {
315         // If there's no number at the head of the string, return 0, and
316         // make 'endptr' point to the start of the string.
317         { .str = "",      .res = 0, .endptr_val = '\0' },
318         { .str = " \n\t", .res = 0, .endptr_val = ' '  },
319         { .str = "one",   .res = 0, .endptr_val = 'o'  },
320         { .str = "\ntwo", .res = 0, .endptr_val = '\n' },
321
322         // Successful conversion.  Leading whitespace is ignored.  A single
323         // '-' or '+' is accepted.
324         { .str =  "0",            .res =       0, .endptr_val = '\0' },
325         { .str = "+0",            .res =       0, .endptr_val = '\0' },
326         { .str = "-0",            .res =       0, .endptr_val = '\0' },
327         { .str =  "1",            .res =       1, .endptr_val = '\0' },
328         { .str = "+1",            .res =       1, .endptr_val = '\0' },
329         { .str = "-1",            .res =      -1, .endptr_val = '\0' },
330         { .str = "12",            .res =      12, .endptr_val = '\0' },
331         { .str = "-567",          .res =    -567, .endptr_val = '\0' },
332         { .str = "1234567",       .res = 1234567, .endptr_val = '\0' },
333         { .str = "007",           .res =       7, .endptr_val = '\0' },
334         { .str = "   +42",        .res =      42, .endptr_val = '\0' },
335         { .str = "\n\t\r\v  -56", .res =     -56, .endptr_val = '\0' },
336         { .str = "123xyz",        .res =     123, .endptr_val = 'x'  },
337         { .str = " -123abc",      .res =    -123, .endptr_val = 'a'  },
338
339         // Whitespace after the +/- is not allowed;  conversion fails.
340         { .str = "+ 1",   .res =  0, .endptr_val = '+' },
341         { .str = "-\n1",  .res =  0, .endptr_val = '-' },
342      };
343
344      // Nb: We test the results against strtoll() as well.
345      int i;
346      for (i = 0; i < (sizeof(a) / sizeof(StrtollInputs)); i++) {
347         HChar* endptr1;
348         HChar* endptr2;
349         Long      res1 = VG_(strtoll10)(a[i].str, &endptr1);
350         long long res2 =     strtoll   (a[i].str, &endptr2, 10);
351         //printf("res1 = %lld, *endptr1 = '%c'\n", res1, *endptr1);
352         //printf("res2 = %lld, *endptr2 = '%c'\n", res2, *endptr2);
353         CHECK(a[i].res == res1 && a[i].endptr_val == *endptr1);
354         CHECK(res2     == res1 && *endptr2        == *endptr1);
355      }
356   }
357
358   // VG_(strtoll16)()
359   {
360      StrtollInputs a[] = {
361         // If there's no number at the head of the string, return 0, and
362         // make 'endptr' point to the start of the string.
363         { .str = "",      .res = 0, .endptr_val = '\0' },
364         { .str = " \n\t", .res = 0, .endptr_val = ' '  },
365         { .str = "one",   .res = 0, .endptr_val = 'o'  },
366         { .str = "\ntwo", .res = 0, .endptr_val = '\n' },
367
368         // Successful conversion.  Leading whitespace is ignored.  A single
369         // '-' or '+' is accepted.  "0X" and "0x" are also allowed at the
370         // front, but if no digits follow, just the "0" is converted.
371         { .str =   "0",           .res =        0, .endptr_val = '\0' },
372         { .str = "0x0",           .res =        0, .endptr_val = '\0' },
373         { .str = "0X0",           .res =        0, .endptr_val = '\0' },
374         { .str = "0x",            .res =        0, .endptr_val = 'x'  },
375         { .str = "0Xg",           .res =        0, .endptr_val = 'X'  },
376         { .str =   "0",           .res =        0, .endptr_val = '\0' },
377         { .str =  "+0",           .res =        0, .endptr_val = '\0' },
378         { .str =  "-0",           .res =        0, .endptr_val = '\0' },
379         { .str =   "1",           .res =        1, .endptr_val = '\0' },
380         { .str =  "+1",           .res =        1, .endptr_val = '\0' },
381         { .str =  "-1",           .res =       -1, .endptr_val = '\0' },
382         { .str =  "1a",           .res =       26, .endptr_val = '\0' },
383         { .str = "-5F7",          .res =    -1527, .endptr_val = '\0' },
384         { .str = "0x1234567",     .res = 19088743, .endptr_val = '\0' },
385         { .str = "007",           .res =        7, .endptr_val = '\0' },
386         { .str = "0X00ABCD",      .res =    43981, .endptr_val = '\0' },
387         { .str = "   +AbC",       .res =     2748, .endptr_val = '\0' },
388         { .str = "   -0xAbC",     .res =    -2748, .endptr_val = '\0' },
389         { .str = "   -0xxx",      .res =        0, .endptr_val = 'x'  },
390         { .str = "\n\t\r\v  -56", .res =      -86, .endptr_val = '\0' },
391         { .str = "123xyz",        .res =      291, .endptr_val = 'x'  },
392         { .str = " -123defghi",   .res = -1195503, .endptr_val = 'g'  },
393
394         // Whitespace after the +/- is not allowed;  conversion fails.
395         { .str = "+ 1",    .res =  0, .endptr_val = '+' },
396         { .str = "-\n0x1", .res =  0, .endptr_val = '-' },
397      };
398
399      // Nb: We test the results against strtoll() as well.
400      int i;
401      for (i = 0; i < (sizeof(a) / sizeof(StrtollInputs)); i++) {
402         HChar* endptr1;
403         HChar* endptr2;
404         Long      res1 = VG_(strtoll16)(a[i].str, &endptr1);
405         long long res2 =     strtoll   (a[i].str, &endptr2, 16);
406         //printf("  res1 = %lld, *endptr1 = '%c'\n", res1, *endptr1);
407         //printf("  res2 = %lld, *endptr2 = '%c'\n", res2, *endptr2);
408         CHECK(a[i].res == res1 && a[i].endptr_val == *endptr1);
409         CHECK(res2     == res1 && *endptr2        == *endptr1);
410      }
411   }
412
413   // VG_(strtod)()
414   // XXX: todo
415}
416
417void test_log2(void)
418{
419   CHECK( -1 == VG_(log2)(0) );
420   CHECK(  0 == VG_(log2)(1) );
421   CHECK(  1 == VG_(log2)(2) );
422   CHECK( -1 == VG_(log2)(3) );
423   CHECK(  2 == VG_(log2)(4) );
424   CHECK( -1 == VG_(log2)(5) );
425   CHECK( -1 == VG_(log2)(6) );
426   CHECK( -1 == VG_(log2)(7) );
427   CHECK(  3 == VG_(log2)(8) );
428
429   CHECK( -1 == VG_(log2)( 15) );
430   CHECK(  4 == VG_(log2)( 16) );
431   CHECK( -1 == VG_(log2)( 17) );
432
433   CHECK( -1 == VG_(log2)( 63) );
434   CHECK(  6 == VG_(log2)( 64) );
435   CHECK( -1 == VG_(log2)( 65) );
436
437   CHECK( -1 == VG_(log2)(255) );
438   CHECK(  8 == VG_(log2)(256) );
439   CHECK( -1 == VG_(log2)(257) );
440
441   CHECK( -1 == VG_(log2)(65535) );
442   CHECK( 16 == VG_(log2)(65536) );
443   CHECK( -1 == VG_(log2)(65537) );
444
445   CHECK( -1 == VG_(log2)(16777215) );
446   CHECK( 24 == VG_(log2)(16777216) );
447   CHECK( -1 == VG_(log2)(16777217) );
448
449   CHECK( -1 == VG_(log2)(2147483647U) );
450   CHECK( 31 == VG_(log2)(2147483648U) );
451   CHECK( -1 == VG_(log2)(2147483649U) );
452
453   CHECK( -1 == VG_(log2)(4294967295U) );    // Max UInt
454}
455
456void test_random(void)
457{
458   // Hmm, it's really hard to unit test a pseudo-random number generator.
459   // So no testing here, sorry.
460}
461
462//-----------------------------------------------------------------------
463// main
464//-----------------------------------------------------------------------
465
466int main(void)
467{
468   // Nb: the order of the tests is based on the order of the code in
469   // m_libcbase.c, except that macros defined in pub_tool_libcbase.h are
470   // tested first.
471
472   //--------------------------------------------------------------------
473   // pub_tool_libcbase.h macros
474   //--------------------------------------------------------------------
475   test_VG_STREQ();
476   test_VG_STREQN();
477   test_VG_IS_XYZ_ALIGNED();
478   test_VG_ROUND_et_al();
479
480   //--------------------------------------------------------------------
481   // Char functions
482   //--------------------------------------------------------------------
483   test_isspace();
484   test_isdigit();
485
486   //--------------------------------------------------------------------
487   // String-to-number functions
488   //--------------------------------------------------------------------
489   test_is_dec_digit();
490   test_is_hex_digit();
491   test_strtoll_and_strtod();
492
493   //--------------------------------------------------------------------
494   // String functions
495   //--------------------------------------------------------------------
496   // XXX: more todo: VG_(str_*)
497
498   //--------------------------------------------------------------------
499   // Mem functions
500   //--------------------------------------------------------------------
501   // XXX: todo: VG_(mem*)
502
503   //--------------------------------------------------------------------
504   // Miscellaneous functions
505   //--------------------------------------------------------------------
506   // XXX: todo: VG_(ssort)
507   test_log2();
508   test_random();
509
510   return 0;
511}
512
513