1 /* Bestimmung einiger Maschinen-Parameter und -Abhängigkeiten */
2 /* und Ausgabe in ein Include-File */
3 /* Bruno Haible 10.9.1991, 12.10.1992, 6.12.1992, 24.10.1993 */
5 /* Auf einigen Systemen werden in <sys/types.h> die Typen uchar, ushort, uint, */
6 /* ulong definiert. Normalerweise reicht _POSIX_SOURCE aus, dies zu verhindern, */
7 /* bei AIX 3.2.5 (rs6000-ibm-aix3.2.5) jedoch nicht. Wir müssen Gewalt anwenden. */
10 #define ushort os_ushort
12 #define ulong os_ulong
26 #ifdef __CHAR_UNSIGNED__
27 typedef signed char schar;
31 typedef unsigned char uchar;
32 typedef unsigned short ushort;
33 typedef unsigned /* int */ uint;
34 typedef unsigned long ulong;
35 typedef long long longlong;
36 typedef unsigned long long ulonglong;
37 typedef int (function)();
39 static int random_table[256] = /* 2048 zufällige Bits, hier von pi */
40 { 0xC9,0x0F,0xDA,0xA2,0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,
41 0x80,0xDC,0x1C,0xD1,0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,
42 0x02,0x0B,0xBE,0xA6,0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,
43 0x8E,0x34,0x04,0xDD,0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,
44 0x30,0x2B,0x0A,0x6D,0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,
45 0x6D,0x51,0xC2,0x45,0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,
46 0xF4,0x4C,0x42,0xE9,0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,
47 0xF4,0x06,0xB7,0xED,0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,
48 0xAE,0x9F,0x24,0x11,0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,
49 0xEC,0xE4,0x5B,0x3D,0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,
50 0x98,0xDA,0x48,0x36,0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,
51 0xFD,0x24,0xCF,0x5F,0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,
52 0x1C,0x62,0xF3,0x56,0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,
53 0x70,0x96,0x96,0x6D,0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,
54 0xF1,0x74,0x6C,0x08,0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,
55 0x2E,0x36,0xCE,0x3B,0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,
56 0x9B,0x27,0x83,0xA2,0xEC,0x07,0xA2,0x8F,0xB5,0xC5,0x5D,0xF0,
57 0x6F,0x4C,0x52,0xC9,0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,
58 0x39,0x95,0x49,0x7C,0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,
59 0x98,0xFA,0x05,0x10,0x15,0x72,0x8E,0x5A,0x8A,0xAA,0xC4,0x2D,
60 0xAD,0x33,0x17,0x0D,0x04,0x50,0x7A,0x33,0xA8,0x55,0x21,0xAB,
63 #define random_table_length (8*256)
64 static int random_position = -1;
65 int next_random_bit(void)
67 if (random_position==random_table_length) random_position = 0;
68 return (random_table[random_position/8] >> (random_position % 8)) & 1;
71 void printf_underscored (const char* string)
73 while (!((c = *string++) == '\0')) { printf("%c",(c==' ' ? '_' : c)); }
76 /* string_length(string) is the same as strlen(string). */
77 /* Better avoid to depend on <string.h>. */
78 int string_length (char* string)
80 while (!(*string++ == '\0')) { count++; }
84 static int char_bitsize, short_bitsize, int_bitsize, long_bitsize;
85 static int uchar_bitsize, ushort_bitsize, uint_bitsize, ulong_bitsize;
86 static boolean char_uchar_same, short_ushort_same, int_uint_same, long_ulong_same;
87 static int pointer_bitsize;
88 static int longlong_bitsize, ulonglong_bitsize;
89 static boolean longlong_ulonglong_same;
92 #define get_unsigned_integer_bitsize(type,where) \
99 if (bits==1000) { bits = -1; break; } \
103 #define get_signed_integer_bitsize(type,unsigned_type,where) \
104 { /* Signed integer overflow is "undefined behaviour" in C99, and gcc-4.3 \
105 (without -fwrapv option) actually does weird things when signed integer \
106 overflow occurs. Therefore perform the addition on the unsigned type. \
107 Drawback: This will not detect cases where the signed type has more bits\
108 than the unsigned type but the same size according to sizeof. Blech. */ \
113 x = (unsigned_type)x + (unsigned_type)x;\
115 if (bits==1000) { bits = -1; break; } \
119 #define print_integer_bitsize(type,typestr,where) \
121 { printf("/* Integers of type %s have %ld bits. */\n",typestr,(long)where); \
122 if (!(typestr[0] == 'u')) \
123 { printf("#define "); printf_underscored(typestr); printf("_bitsize %ld\n",(long)where); } \
127 { printf("#error \"Integers of type %s have no binary representation!!\"\n",typestr); } \
128 if (!(where == char_bitsize * sizeof(type))) \
129 { printf("#error \"Formula BITSIZE(T) = SIZEOF(T) * BITSPERBYTE does not hold for type %s!!\"\n",typestr); } \
131 get_signed_integer_bitsize(schar,uchar,char_bitsize);
132 get_signed_integer_bitsize(short,ushort,short_bitsize);
133 get_signed_integer_bitsize(int,uint,int_bitsize);
134 get_signed_integer_bitsize(long,ulong,long_bitsize);
135 print_integer_bitsize(schar,"char",char_bitsize);
136 print_integer_bitsize(short,"short",short_bitsize);
137 print_integer_bitsize(int,"int",int_bitsize);
138 print_integer_bitsize(long,"long",long_bitsize);
139 get_signed_integer_bitsize(longlong,ulonglong,longlong_bitsize);
140 print_integer_bitsize(longlong,"long long",longlong_bitsize);
141 get_unsigned_integer_bitsize(uchar,uchar_bitsize);
142 get_unsigned_integer_bitsize(ushort,ushort_bitsize);
143 get_unsigned_integer_bitsize(uint,uint_bitsize);
144 get_unsigned_integer_bitsize(ulong,ulong_bitsize);
145 print_integer_bitsize(uchar,"unsigned char",uchar_bitsize);
146 print_integer_bitsize(ushort,"unsigned short",ushort_bitsize);
147 print_integer_bitsize(uint,"unsigned int",uint_bitsize);
148 print_integer_bitsize(ulong,"unsigned long",ulong_bitsize);
149 get_unsigned_integer_bitsize(ulonglong,ulonglong_bitsize);
150 print_integer_bitsize(ulonglong,"unsigned long long",ulonglong_bitsize);
154 #define compare_integer_bitsizes(typestr1,typestr2,type1_bitsize,type2_bitsize) \
155 { if (!(type1_bitsize==type2_bitsize)) \
156 printf("#error \"Integer types %s and %s have different sizes!!\"\n",typestr1,typestr2); \
158 compare_integer_bitsizes("char","unsigned char",char_bitsize,uchar_bitsize);
159 compare_integer_bitsizes("short","unsigned short",short_bitsize,ushort_bitsize);
160 compare_integer_bitsizes("int","unsigned int",int_bitsize,uint_bitsize);
161 compare_integer_bitsizes("long","unsigned long",long_bitsize,ulong_bitsize);
162 compare_integer_bitsizes("long long","unsigned long long",longlong_bitsize,ulonglong_bitsize);
165 #define get_a_random(type,bitsize,where) \
168 while (i>0) { x = (x<<1) + next_random_bit(); i--; } \
171 #define get_a_random_twice(type1,type2,bitsize,where1,where2) \
172 { type1 x1 = 0; type2 x2 = 0; \
175 { type1 b = next_random_bit(); \
176 x1 = ((x1<<1) + b); x2 = ((x2<<1) + b); \
179 where1 = x1; where2 = x2; \
183 #define compare_integer_representation(type1,type2,typestr1,typestr2,type1_bitsize,type2_bitsize,where) \
184 { if ((type1_bitsize>=0) && (type2_bitsize>=0) && (type1_bitsize==type2_bitsize)) \
186 type1 sample1; type2 sample2; \
188 for (i = 0; i<100; i++) \
189 { get_a_random_twice(type1,type2,type1_bitsize,sample1,sample2); \
190 if (!(sample1 == (type1)(sample2))) { where = FALSE; } \
191 if (!(sample2 == (type2)(sample1))) { where = FALSE; } \
193 for (i = 0; i<100; i++) \
194 { get_a_random(type1,type1_bitsize,sample1); \
195 sample2 = (type2)(sample1); \
196 for (j = 0; j < type1_bitsize; j++) \
197 if (!( ((sample1 & ((type1)1<<j)) == 0) \
198 == ((sample2 & ((type2)1<<j)) == 0) \
203 { printf("/* Integer types %s and %s have the same binary representation. */\n",typestr1,typestr2); } \
205 { printf("#error \"Integer types %s and %s have different binary representations!!\"\n",typestr1,typestr2); } \
210 compare_integer_representation(schar,uchar,"char","unsigned char",char_bitsize,uchar_bitsize,char_uchar_same);
211 compare_integer_representation(short,ushort,"short","unsigned short",short_bitsize,ushort_bitsize,short_ushort_same);
212 compare_integer_representation(int,uint,"int","unsigned int",int_bitsize,uint_bitsize,int_uint_same);
213 compare_integer_representation(long,ulong,"long","unsigned long",long_bitsize,ulong_bitsize,long_ulong_same);
214 compare_integer_representation(longlong,ulonglong,"long long","unsigned long long",longlong_bitsize,ulonglong_bitsize,longlong_ulonglong_same);
219 #define test_integer_ushift(type,typestr,type_bitsize) \
220 if (type_bitsize >= 0) \
222 type sample1,sample2; \
223 boolean left_works = TRUE, right_works = TRUE; \
224 for (i = 0; i<100; i++) \
225 { get_a_random(type,type_bitsize,sample1); \
226 for (shc = 0; shc < type_bitsize; shc++) \
227 { sample2 = sample1 << shc; \
228 for (j=0; j < type_bitsize; j++) \
229 { if (!( ((sample2 & ((type)1<<j)) == 0) \
231 (j < shc ? TRUE : ((sample1 & ((type)1<<(j-shc))) == 0)) \
233 { left_works = FALSE; } \
235 for (i = 0; i<100; i++) \
236 { get_a_random(type,type_bitsize,sample1); \
237 for (shc = 0; shc < type_bitsize; shc++) \
238 { sample2 = sample1 >> shc; \
239 for (j=0; j < type_bitsize; j++) \
240 { if (!( ((sample2 & ((type)1<<j)) == 0) \
242 (j >= type_bitsize-shc ? TRUE : ((sample1 & ((type)1<<(j+shc))) == 0)) \
244 { right_works = FALSE; } \
247 { printf("#error \"Left shift of integers of type %s does not work!!\"\n",typestr); } \
249 { printf("#error \"Right shift of integers of type %s does not work!!\"\n",typestr); } \
251 #define test_integer_sshift(type,typestr,type_bitsize) \
252 if (type_bitsize >= 0) \
254 type sample1,sample2; \
255 boolean left_works = TRUE, right_works = TRUE; \
256 for (i = 0; i<100; i++) \
257 { get_a_random(type,type_bitsize,sample1); \
258 for (shc = 0; shc < type_bitsize; shc++) \
259 { sample2 = sample1 << shc; \
260 for (j=0; j < type_bitsize; j++) \
261 { if (!( ((sample2 & ((type)1<<j)) == 0) \
263 (j < shc ? TRUE : ((sample1 & ((type)1<<(j-shc))) == 0)) \
265 { left_works = FALSE; } \
267 for (i = 0; i<100; i++) \
268 { get_a_random(type,type_bitsize,sample1); \
269 for (shc = 0; shc < type_bitsize; shc++) \
270 { sample2 = sample1 >> shc; \
271 for (j=0; j < type_bitsize; j++) \
272 { if (!( ((sample2 & ((type)1<<j)) == 0) \
274 ((sample1 & ((type)1<< (j+shc>=type_bitsize ? type_bitsize-1 : j+shc))) == 0) \
276 { right_works = FALSE; } \
279 { printf("#error \"Left shift of integers of type %s does not work!!\"\n",typestr); } \
281 { printf("#error \"Right shift of integers of type %s does not work!!\"\n",typestr); } \
283 test_integer_ushift(uchar,"unsigned char",uchar_bitsize);
284 test_integer_ushift(ushort,"unsigned short",ushort_bitsize);
285 test_integer_ushift(uint,"unsigned int",uint_bitsize);
286 test_integer_ushift(ulong,"unsigned long",ulong_bitsize);
287 test_integer_ushift(ulonglong,"unsigned long long",ulonglong_bitsize);
288 test_integer_sshift(schar,"char",char_bitsize);
289 test_integer_sshift(short,"short",short_bitsize);
290 test_integer_sshift(int,"int",int_bitsize);
291 test_integer_sshift(long,"long",long_bitsize);
292 test_integer_sshift(longlong,"long long",longlong_bitsize);
296 #define test_integer_casts(type1,type2,typestr1,typestr2,type1_bitsize,type2_bitsize,want) \
297 if (type1_bitsize <= type2_bitsize) \
299 boolean modifies = FALSE; \
300 boolean zero_extends = TRUE; \
301 boolean sign_extends = TRUE; \
302 for (i = 0; i<100; i++) \
305 get_a_random(type1,type1_bitsize,sample1); \
306 sample2 = (type2)sample1; \
307 if (!(sample1 == (type1)sample2)) { modifies = TRUE; } \
308 for (j = 0; j<type1_bitsize; j++) \
309 if (!( ((sample1 & ((type1)1<<j)) == 0) == ((sample2 & ((type2)1<<j)) == 0) )) \
310 { zero_extends = FALSE; sign_extends = FALSE; } \
311 for (j = type1_bitsize; j<type2_bitsize; j++) \
312 if (!((sample2 & ((type2)1<<j)) == 0)) \
313 { zero_extends = FALSE; } \
314 for (j = type1_bitsize; j<type2_bitsize; j++) \
315 if (!( ((sample1 & ((type1)1<<(type1_bitsize-1))) == 0) == ((sample2 & ((type2)1<<j)) == 0) )) \
316 { sign_extends = FALSE; } \
319 printf("#error \"Casts: (%s)(%s)(x) == x does not hold for every %s x !!\"\n",typestr1,typestr2,typestr1); \
320 if (zero_extends && sign_extends) \
321 { if (!(type1_bitsize == type2_bitsize)) \
322 printf("#error \"Casts from %s to %s works by identity!!\"\n",typestr1,typestr2); \
324 if (zero_extends && !sign_extends) \
325 { if ((type1_bitsize == type2_bitsize) || !(typestr1[0] == 'u') || !(want==1)) \
326 printf("#error \"Casts from %s to %s works by zero-extend!!\"\n",typestr1,typestr2); \
328 if (sign_extends && !zero_extends) \
329 { if ((type1_bitsize == type2_bitsize) || (typestr1[0] == 'u') || !(want==2)) \
330 printf("#error \"Casts from %s to %s works by sign-extend!!\"\n",typestr1,typestr2); \
332 if (!sign_extends && !zero_extends) \
333 printf("#error \"Casts from %s to %s works in an unknown manner!!\"\n",typestr1,typestr2); \
335 /* erst Casts zwischen Integers vermutlich gleicher Größe: */
336 test_integer_casts(schar,uchar,"char","unsigned char",char_bitsize,uchar_bitsize,0);
337 test_integer_casts(short,ushort,"short","unsigned short",short_bitsize,ushort_bitsize,0);
338 test_integer_casts(int,uint,"int","unsigned int",int_bitsize,uint_bitsize,0);
339 test_integer_casts(long,ulong,"long","unsigned long",long_bitsize,ulong_bitsize,0);
340 test_integer_casts(uchar,schar,"unsigned char","char",uchar_bitsize,char_bitsize,0);
341 test_integer_casts(ushort,short,"unsigned short","short",ushort_bitsize,short_bitsize,0);
342 test_integer_casts(uint,int,"unsigned int","int",uint_bitsize,int_bitsize,0);
343 test_integer_casts(ulong,long,"unsigned long","long",ulong_bitsize,long_bitsize,0);
344 test_integer_casts(longlong,ulonglong,"long long","unsigned long long",longlong_bitsize,ulonglong_bitsize,0);
345 test_integer_casts(ulonglong,longlong,"unsigned long long","long long",ulonglong_bitsize,longlong_bitsize,0);
346 /* dann Casts zwischen Integers unterschiedlicher Größe, aber gleichen Vorzeichens: */
347 test_integer_casts(uchar,ushort,"unsigned char","unsigned short",uchar_bitsize,ushort_bitsize,1);
348 test_integer_casts(uchar,uint,"unsigned char","unsigned int",uchar_bitsize,uint_bitsize,1);
349 test_integer_casts(uchar,ulong,"unsigned char","unsigned long",uchar_bitsize,ulong_bitsize,1);
350 test_integer_casts(ushort,uint,"unsigned short","unsigned int",ushort_bitsize,uint_bitsize,1);
351 test_integer_casts(ushort,ulong,"unsigned short","unsigned long",ushort_bitsize,ulong_bitsize,1);
352 test_integer_casts(uint,ulong,"unsigned int","unsigned long",uint_bitsize,ulong_bitsize,1);
353 test_integer_casts(uchar,ulonglong,"unsigned char","unsigned long long",uchar_bitsize,ulonglong_bitsize,1);
354 test_integer_casts(ushort,ulonglong,"unsigned short","unsigned long long",ushort_bitsize,ulonglong_bitsize,1);
355 test_integer_casts(uint,ulonglong,"unsigned int","unsigned long long",uint_bitsize,ulonglong_bitsize,1);
356 test_integer_casts(ulong,ulonglong,"unsigned long","unsigned long long",ulong_bitsize,ulonglong_bitsize,1);
357 test_integer_casts(schar,short,"char","short",char_bitsize,short_bitsize,2);
358 test_integer_casts(schar,int,"char","int",char_bitsize,int_bitsize,2);
359 test_integer_casts(schar,long,"char","long",char_bitsize,long_bitsize,2);
360 test_integer_casts(short,int,"short","int",short_bitsize,int_bitsize,2);
361 test_integer_casts(short,long,"short","long",short_bitsize,long_bitsize,2);
362 test_integer_casts(int,long,"int","long",int_bitsize,long_bitsize,2);
363 test_integer_casts(schar,longlong,"char","long long",char_bitsize,longlong_bitsize,2);
364 test_integer_casts(short,longlong,"short","long long",short_bitsize,longlong_bitsize,2);
365 test_integer_casts(int,longlong,"int","long long",int_bitsize,longlong_bitsize,2);
366 test_integer_casts(long,longlong,"long","long long",long_bitsize,longlong_bitsize,2);
367 /* dann Casts zwischen Integers unterschiedlicher Größe und unterschiedlichen Vorzeichens: */
368 test_integer_casts(uchar,short,"unsigned char","short",uchar_bitsize,short_bitsize,1);
369 test_integer_casts(uchar,int,"unsigned char","int",uchar_bitsize,int_bitsize,1);
370 test_integer_casts(uchar,long,"unsigned char","long",uchar_bitsize,long_bitsize,1);
371 test_integer_casts(ushort,int,"unsigned short","int",ushort_bitsize,int_bitsize,1);
372 test_integer_casts(ushort,long,"unsigned short","long",ushort_bitsize,long_bitsize,1);
373 test_integer_casts(uint,long,"unsigned int","long",uint_bitsize,long_bitsize,1);
374 test_integer_casts(uchar,longlong,"unsigned char","long long",uchar_bitsize,longlong_bitsize,1);
375 test_integer_casts(ushort,longlong,"unsigned short","long long",ushort_bitsize,longlong_bitsize,1);
376 test_integer_casts(uint,longlong,"unsigned int","long long",uint_bitsize,longlong_bitsize,1);
377 test_integer_casts(ulong,longlong,"unsigned long","long long",ulong_bitsize,longlong_bitsize,1);
378 test_integer_casts(schar,ushort,"char","unsigned short",char_bitsize,ushort_bitsize,2);
379 test_integer_casts(schar,uint,"char","unsigned int",char_bitsize,uint_bitsize,2);
380 test_integer_casts(schar,ulong,"char","unsigned long",char_bitsize,ulong_bitsize,2);
381 test_integer_casts(short,uint,"short","unsigned int",short_bitsize,uint_bitsize,2);
382 test_integer_casts(short,ulong,"short","unsigned long",short_bitsize,ulong_bitsize,2);
383 test_integer_casts(int,ulong,"int","unsigned long",int_bitsize,ulong_bitsize,2);
384 test_integer_casts(schar,ulonglong,"char","unsigned long long",char_bitsize,ulonglong_bitsize,2);
385 test_integer_casts(short,ulonglong,"short","unsigned long long",short_bitsize,ulonglong_bitsize,2);
386 test_integer_casts(int,ulonglong,"int","unsigned long long",int_bitsize,ulonglong_bitsize,2);
387 test_integer_casts(long,ulonglong,"long","unsigned long long",long_bitsize,ulonglong_bitsize,2);
391 #define check_sizeof_pointer(type,typestr) \
392 { if (!(sizeof(type) <= sizeof(intptr_t))) \
393 printf("#error \"Type %s does not fit into an intptr_t!!\"\n",typestr); \
395 check_sizeof_pointer(char*,"char *");
396 check_sizeof_pointer(long*,"long *");
397 check_sizeof_pointer(function*,"function *");
398 pointer_bitsize = char_bitsize * sizeof(char*);
399 printf("/* Pointers of type %s have %ld bits. */\n","char *",(long)pointer_bitsize);
400 printf("#define pointer_bitsize %ld\n",(long)pointer_bitsize);
405 #define test_pointer_casts(type1,type2,typestr1,typestr2) \
406 if (!(sizeof(type1) == sizeof(type2))) \
407 { printf("#error \"Pointer types %s and %s have different sizes!!\"\n",typestr1,typestr2); } \
410 uintptr_t differences1 = 0, differences2 = 0; \
411 for (i = 0; i<100; i++) \
412 { uintptr_t sample; \
415 get_a_random(uintptr_t,pointer_bitsize,sample); \
416 sample1 = (type1)sample; \
417 sample2 = (type2)sample; \
418 differences1 |= ((uintptr_t)sample1 ^ (uintptr_t)(type1)(sample2)); \
419 differences2 |= ((uintptr_t)sample2 ^ (uintptr_t)(type2)(sample1)); \
421 if (differences1==0) \
422 printf("/* Casts from %s to %s is OK (does nothing). */\n",typestr2,typestr1); \
424 if (differences1 == ~(uintptr_t)0) \
425 printf("#error \"Casts from %s to %s work in an unknown way!!\"\n",typestr2,typestr1); \
427 printf("#error \"Casts from %s to %s modify part 0x%8lX of pointer!!\"\n",typestr2,typestr1,differences1); \
428 if (differences2==0) \
429 printf("/* Casts from %s to %s is OK (does nothing). */\n",typestr1,typestr2); \
431 if (differences2 == ~(uintptr_t)0) \
432 printf("#error \"Casts from %s to %s work in an unknown way!!\"\n",typestr1,typestr2); \
434 printf("#error \"Casts from %s to %s modify part 0x%8lX of pointer!!\"\n",typestr1,typestr2,differences2); \
436 test_pointer_casts(char*,long*,"char *","long *");
437 test_pointer_casts(char*,function*,"char *","function *");
442 /* The following macro works only in C, not in C++, because C++ restricts the
443 use of NULL pointers and also because C++ forbids defining types within a
445 #define alignmentof(type) \
446 (int)(&((struct { char dummy1; type dummy2; } *)0)->dummy2)
447 #define get_alignment(type,typestr) \
448 { struct { char dummy1; type dummy2; } dummy; \
449 long alignment = (char*)&dummy.dummy2 - (char*)&dummy; \
450 printf("/* Type %s has sizeof = %ld and alignment = %ld. */\n",typestr,(long)sizeof(type),alignment); \
451 if (!(typestr[0] == 'u') && !(typestr[string_length(typestr)-1] == '*')) \
452 { printf("#define sizeof_"); printf_underscored(typestr); printf(" %ld\n",(long)sizeof(type)); \
453 printf("#define alignment_"); printf_underscored(typestr); printf(" %ld\n",alignment); \
455 if (!((alignment & (alignment-1)) == 0)) \
456 printf("#error \"The alignment %ld of type %s is not a power of two!!\"\n",alignment,typestr); \
459 get_alignment(char,"char"); get_alignment(uchar,"unsigned char");
460 get_alignment(short,"short"); get_alignment(ushort,"unsigned short");
461 get_alignment(int,"int"); get_alignment(uint,"unsigned int");
462 get_alignment(long,"long"); get_alignment(ulong,"unsigned long");
463 get_alignment(longlong,"long long"); get_alignment(ulonglong,"unsigned long long");
464 get_alignment(float,"float");
465 get_alignment(double,"double");
466 get_alignment(char*,"char *");
467 get_alignment(long*,"long *");
468 get_alignment(function*,"function *");
472 #define get_endian(type,typestr,type_bitsize) \
473 { if (type_bitsize == uchar_bitsize * sizeof(type)) \
474 { union { uchar einzeln[sizeof(type)]; type gesamt; } x; \
476 boolean big_endian = TRUE; \
477 boolean little_endian = TRUE; \
478 for (i = 0; i<100; i++) \
480 get_a_random(type,type_bitsize,sample); \
482 for (j = 0; j<sizeof(type); j++, sample >>= uchar_bitsize) \
483 { if (!( (sample & (((type)1<<uchar_bitsize)-1)) == x.einzeln[j] )) \
484 { little_endian = FALSE; } \
485 if (!( (sample & (((type)1<<uchar_bitsize)-1)) == x.einzeln[sizeof(type)-1-j] )) \
486 { big_endian = FALSE; } \
488 if (big_endian && little_endian) \
489 { if (!(sizeof(type) == 1)) \
490 printf("#error \"Endianness of type %s in memory doesn't matter.\"\n",typestr); } \
491 if (big_endian && !little_endian) \
492 { printf("/* Type %s is stored BIG-ENDIAN in memory (i.e. like mc68000 or sparc). */\n",typestr); \
493 printf("#define "); printf_underscored(&typestr[9]); printf("_big_endian\n"); \
495 if (little_endian && !big_endian) \
496 { printf("/* Type %s is stored LITTLE-ENDIAN in memory (i.e. like Z80 or VAX). */\n",typestr); \
497 printf("#define "); printf_underscored(&typestr[9]); printf("_little_endian\n"); \
499 if (!big_endian && !little_endian) \
500 { printf("#error \"Type %s is stored in memory in an obscure manner!!\"\n",typestr); } \
503 { printf("#error \"Endianness makes no sense for type %s !!\"\n",typestr); } \
505 get_endian(ushort,"unsigned short",ushort_bitsize);
506 get_endian(uint,"unsigned int",uint_bitsize);
507 get_endian(ulong,"unsigned long",ulong_bitsize);
508 get_endian(ulonglong,"unsigned long long",ulonglong_bitsize);
512 int main(int argc, char *argv[])
513 { if (freopen(argc==1 ? "conftest.h" : argv[1], "w", stdout) == NULL) return 1;
523 if (ferror(stdout) || fclose(stdout)) return 1;