Home | History | Annotate | Download | only in tests
      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)
     15 unsigned long VKI_PAGE_SIZE  = 1UL << 12;
     16 #elif defined(VGP_arm64_linux)
     17 unsigned long VKI_PAGE_SIZE  = 1UL << 16;
     18 #elif defined(VGP_mips32_linux) || defined(VGP_mips64_linux)
     19 #include <unistd.h>
     20 unsigned long VKI_PAGE_SIZE;
     21 #endif
     22 
     23 /* Provide a stub to not have to pull in m_debuglog.c */
     24 void 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 */
     35 void 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 
     45 void 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 
     62 void 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 
     88 void 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 
    194 void 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 
    287 void 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 
    296 void 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 
    306 void 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 
    314 void 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 
    326 void 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 
    440 void 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 
    479 void 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 
    489 int 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