You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

153 lines
4.2 KiB

#define GLUE_HELPER(x, y) x ## _ ## y
#define GLUE(x, y) GLUE_HELPER(x, y)
#define TOSTRING(x) #x
static const char *GLUE(make_string, TYPE_FUNC)(TYPE value, int base)
{
static char buffer[66];
char *s; /* allows 64-bit base 2 value with minus and null */
TYPEU valuetemp;
/* build number string in proper base, work backwards, starting with null */
s = buffer + sizeof(buffer);
*--s = 0;
/* fill in the digits */
valuetemp = (value < 0) ? -value : value;
do
{
*--s = "0123456789abcdefghijklmnopqrstuvwxyz"[valuetemp % base];
valuetemp /= base;
} while (valuetemp);
/* add sign if needed */
if (value < 0)
*--s = '-';
return s;
}
static void GLUE(e, TYPE_FUNC)(int n, const char *s, TYPE result, int base)
{
/* watch out: don't overwrite the static buffer in make_string */
printf("Subtest %s, error %d, errno=%d, s=\"%s\", base=%d, ", TOSTRING(TYPE_FUNC), n, errno, s, base);
printf("result=%s\n", GLUE(make_string, TYPE_FUNC)(result, base));
e(7);
}
static void GLUE(test_string, TYPE_FUNC)(const char *s, TYPE value, int base)
{
char *end;
TYPE result;
/* must convert the entire string, resulting in the requested value */
result = TYPE_FUNC(s, &end, base);
if (result != value) GLUE(e, TYPE_FUNC)(1, s, result, base);
if (*end) GLUE(e, TYPE_FUNC)(2, s, result, base);
}
static void GLUE(test_value_with_base, TYPE_FUNC)(TYPE value, int base)
{
const char *s;
/* convert to string, then convert back */
s = GLUE(make_string, TYPE_FUNC)(value, base);
GLUE(test_string, TYPE_FUNC)(s, value, base);
}
static void GLUE(test_value, TYPE_FUNC)(TYPE value)
{
int base;
/* let's get all our bases covered */
for (base = 2; base <= 36; base++)
GLUE(test_value_with_base, TYPE_FUNC)(value, base);
}
static void GLUE(test, TYPE_FUNC)(void)
{
int base, i;
TYPE value, valuenext;
/* check 0x0000.... and 0xffff.... */
value = 0;
for (i = 0; i < 0x10000; i++)
{
/* test current value */
GLUE(test_value, TYPE_FUNC)(value);
GLUE(test_value, TYPE_FUNC)(-value);
value++;
}
/* check 0x8000.... and 0x7fff.... */
value = 0;
value = ((~value) << 1) >> 1;
for (i = 0; i < 0x10000; i++)
{
/* test current value */
GLUE(test_value, TYPE_FUNC)(value);
GLUE(test_value, TYPE_FUNC)(-value);
value++;
}
/* check powers of possible bases */
for (base = 2; base <= 36; base++)
{
value = 1;
while (1)
{
/* test current value with offsets */
for (i = -36; i <= 36; i++)
{
GLUE(test_value, TYPE_FUNC)(value + i);
GLUE(test_value, TYPE_FUNC)(-value + i);
}
/* stop after overflow */
valuenext = value * base;
if (valuenext <= value)
break;
value = valuenext;
}
}
/* automatic base */
GLUE(test_string, TYPE_FUNC)("10", 10, 0);
GLUE(test_string, TYPE_FUNC)("010", 010, 0);
GLUE(test_string, TYPE_FUNC)("010", 010, 8);
GLUE(test_string, TYPE_FUNC)("0x10", 0x10, 0);
GLUE(test_string, TYPE_FUNC)("0X10", 0X10, 0);
GLUE(test_string, TYPE_FUNC)("0x10", 0x10, 16);
GLUE(test_string, TYPE_FUNC)("0X10", 0X10, 16);
/* ignore plus sign, leading spaces and zeroes */
GLUE(test_string, TYPE_FUNC)("10", 10, 10);
GLUE(test_string, TYPE_FUNC)("010", 10, 10);
GLUE(test_string, TYPE_FUNC)("0010", 10, 10);
GLUE(test_string, TYPE_FUNC)(" 10", 10, 10);
GLUE(test_string, TYPE_FUNC)(" 010", 10, 10);
GLUE(test_string, TYPE_FUNC)(" 0010", 10, 10);
GLUE(test_string, TYPE_FUNC)("\t10", 10, 10);
GLUE(test_string, TYPE_FUNC)("\t010", 10, 10);
GLUE(test_string, TYPE_FUNC)("\t0010", 10, 10);
GLUE(test_string, TYPE_FUNC)(" \t10", 10, 10);
GLUE(test_string, TYPE_FUNC)(" \t010", 10, 10);
GLUE(test_string, TYPE_FUNC)(" \t0010", 10, 10);
GLUE(test_string, TYPE_FUNC)("+10", 10, 10);
GLUE(test_string, TYPE_FUNC)("+010", 10, 10);
GLUE(test_string, TYPE_FUNC)("+0010", 10, 10);
GLUE(test_string, TYPE_FUNC)(" +10", 10, 10);
GLUE(test_string, TYPE_FUNC)(" +010", 10, 10);
GLUE(test_string, TYPE_FUNC)(" +0010", 10, 10);
GLUE(test_string, TYPE_FUNC)("\t+10", 10, 10);
GLUE(test_string, TYPE_FUNC)("\t+010", 10, 10);
GLUE(test_string, TYPE_FUNC)("\t+0010", 10, 10);
GLUE(test_string, TYPE_FUNC)(" \t+10", 10, 10);
GLUE(test_string, TYPE_FUNC)(" \t+010", 10, 10);
GLUE(test_string, TYPE_FUNC)(" \t+0010", 10, 10);
}
#undef GLUE_HELPER
#undef GLUE
#undef TOSTRING