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