xref: /minix/minix/tests/test45.h (revision 433d6423)
1 #define GLUE_HELPER(x, y) x ## _ ## y
2 #define GLUE(x, y) GLUE_HELPER(x, y)
3 #define TOSTRING(x) #x
4 
GLUE(make_string,TYPE_FUNC)5 static const char *GLUE(make_string, TYPE_FUNC)(TYPE value, int base)
6 {
7 	static char buffer[66];
8 	char *s; /* allows 64-bit base 2 value with minus and null */
9 	TYPEU valuetemp;
10 
11 	/* build number string in proper base, work backwards, starting with null */
12 	s = buffer + sizeof(buffer);
13 	*--s = 0;
14 
15 	/* fill in the digits */
16 	valuetemp = (value < 0) ? -value : value;
17 	do
18 	{
19 		*--s = "0123456789abcdefghijklmnopqrstuvwxyz"[valuetemp % base];
20 		valuetemp /= base;
21 	} while (valuetemp);
22 
23 	/* add sign if needed */
24 	if (value < 0)
25 		*--s = '-';
26 
27 	return s;
28 }
29 
GLUE(e,TYPE_FUNC)30 static void GLUE(e, TYPE_FUNC)(int n, const char *s, TYPE result, int base)
31 {
32 	/* watch out: don't overwrite the static buffer in make_string */
33 	printf("Subtest %s, error %d, errno=%d, s=\"%s\", base=%d, ", TOSTRING(TYPE_FUNC), n, errno, s, base);
34 	printf("result=%s\n", GLUE(make_string, TYPE_FUNC)(result, base));
35 	e(7);
36 }
37 
GLUE(test_string,TYPE_FUNC)38 static void GLUE(test_string, TYPE_FUNC)(const char *s, TYPE value, int base)
39 {
40 	char *end;
41 	TYPE result;
42 
43 	/* must convert the entire string, resulting in the requested value */
44 	result = TYPE_FUNC(s, &end, base);
45 	if (result != value) GLUE(e, TYPE_FUNC)(1, s, result, base);
46 	if (*end) GLUE(e, TYPE_FUNC)(2, s, result, base);
47 }
48 
GLUE(test_value_with_base,TYPE_FUNC)49 static void GLUE(test_value_with_base, TYPE_FUNC)(TYPE value, int base)
50 {
51 	const char *s;
52 
53 	/* convert to string, then convert back */
54 	s = GLUE(make_string, TYPE_FUNC)(value, base);
55 	GLUE(test_string, TYPE_FUNC)(s, value, base);
56 }
57 
GLUE(test_value,TYPE_FUNC)58 static void GLUE(test_value, TYPE_FUNC)(TYPE value)
59 {
60 	int base;
61 
62 	/* let's get all our bases covered */
63 	for (base = 2; base <= 36; base++)
64 		GLUE(test_value_with_base, TYPE_FUNC)(value, base);
65 }
66 
GLUE(test,TYPE_FUNC)67 static void GLUE(test, TYPE_FUNC)(void)
68 {
69 	int base, i;
70 	TYPE value, valuenext;
71 
72 	/* check 0x0000.... and 0xffff.... */
73 	value = 0;
74 	for (i = 0; i < 0x10000; i++)
75 	{
76 		/* test current value */
77 		GLUE(test_value, TYPE_FUNC)(value);
78 		GLUE(test_value, TYPE_FUNC)(-value);
79 		value++;
80 	}
81 
82 	/* check 0x8000.... and 0x7fff.... */
83 	value = 0;
84 	value = ((~value) << 1) >> 1;
85 	for (i = 0; i < 0x10000; i++)
86 	{
87 		/* test current value */
88 		GLUE(test_value, TYPE_FUNC)(value);
89 		GLUE(test_value, TYPE_FUNC)(-value);
90 		value++;
91 	}
92 
93 	/* check powers of possible bases */
94 	for (base = 2; base <= 36; base++)
95 	{
96 		value = 1;
97 		while (1)
98 		{
99 			/* test current value with offsets */
100 			for (i = -36; i <= 36; i++)
101 			{
102 				GLUE(test_value, TYPE_FUNC)(value + i);
103 				GLUE(test_value, TYPE_FUNC)(-value + i);
104 			}
105 
106 			/* stop after overflow */
107 			valuenext = value * base;
108 			if (valuenext <= value)
109 				break;
110 
111 			value = valuenext;
112 		}
113 	}
114 
115 	/* automatic base */
116 	GLUE(test_string, TYPE_FUNC)("10",  10,  0);
117 	GLUE(test_string, TYPE_FUNC)("010", 010, 0);
118 	GLUE(test_string, TYPE_FUNC)("010", 010, 8);
119 	GLUE(test_string, TYPE_FUNC)("0x10", 0x10, 0);
120 	GLUE(test_string, TYPE_FUNC)("0X10", 0X10, 0);
121 	GLUE(test_string, TYPE_FUNC)("0x10", 0x10, 16);
122 	GLUE(test_string, TYPE_FUNC)("0X10", 0X10, 16);
123 
124 	/* ignore plus sign, leading spaces and zeroes */
125 	GLUE(test_string, TYPE_FUNC)("10", 10, 10);
126 	GLUE(test_string, TYPE_FUNC)("010", 10, 10);
127 	GLUE(test_string, TYPE_FUNC)("0010", 10, 10);
128 	GLUE(test_string, TYPE_FUNC)(" 10", 10, 10);
129 	GLUE(test_string, TYPE_FUNC)(" 010", 10, 10);
130 	GLUE(test_string, TYPE_FUNC)(" 0010", 10, 10);
131 	GLUE(test_string, TYPE_FUNC)("\t10", 10, 10);
132 	GLUE(test_string, TYPE_FUNC)("\t010", 10, 10);
133 	GLUE(test_string, TYPE_FUNC)("\t0010", 10, 10);
134 	GLUE(test_string, TYPE_FUNC)(" \t10", 10, 10);
135 	GLUE(test_string, TYPE_FUNC)(" \t010", 10, 10);
136 	GLUE(test_string, TYPE_FUNC)(" \t0010", 10, 10);
137 	GLUE(test_string, TYPE_FUNC)("+10", 10, 10);
138 	GLUE(test_string, TYPE_FUNC)("+010", 10, 10);
139 	GLUE(test_string, TYPE_FUNC)("+0010", 10, 10);
140 	GLUE(test_string, TYPE_FUNC)(" +10", 10, 10);
141 	GLUE(test_string, TYPE_FUNC)(" +010", 10, 10);
142 	GLUE(test_string, TYPE_FUNC)(" +0010", 10, 10);
143 	GLUE(test_string, TYPE_FUNC)("\t+10", 10, 10);
144 	GLUE(test_string, TYPE_FUNC)("\t+010", 10, 10);
145 	GLUE(test_string, TYPE_FUNC)("\t+0010", 10, 10);
146 	GLUE(test_string, TYPE_FUNC)(" \t+10", 10, 10);
147 	GLUE(test_string, TYPE_FUNC)(" \t+010", 10, 10);
148 	GLUE(test_string, TYPE_FUNC)(" \t+0010", 10, 10);
149 }
150 
151 #undef GLUE_HELPER
152 #undef GLUE
153 #undef TOSTRING
154