1iff AST_COMMON 2hdr pthread,stdarg,stddef,stdint,inttypes,types,unistd 3sys types 4typ long.double,size_t,ssize_t 5typ __va_list stdio.h 6 7mac SF_APPEND,SF_CLOSE sys/stat.h sys/socket.h 8 9dll import note{ Microsoft import/export nonsense }end execute{ 10 __declspec(dllimport) int foo; 11 int main() { return foo == 5 ? 0 : 1; } 12 int bar = 5; 13 int* _imp__foo = &bar; 14}end 15 16std proto note{ standard C prototypes ok }end compile{ 17 extern int foo(int, int); 18 bar() { foo(1, 1); } 19}end 20 21tst ptr_void note{ standard C void* ok }end compile{ 22 extern void* foo(); 23 void* bar() { return foo(); } 24}end 25 26cat{ 27 /* disable non-standard linux/gnu inlines */ 28 #ifdef __GNUC__ 29 # undef __OPTIMIZE_SIZE__ 30 # define __OPTIMIZE_SIZE__ 1 31 #endif 32 33 /* __STD_C indicates that the language is ANSI-C or C++ */ 34 #if !defined(__STD_C) && __STDC__ 35 # define __STD_C 1 36 #endif 37 #if !defined(__STD_C) && (__cplusplus || c_plusplus) 38 # define __STD_C 1 39 #endif 40 #if !defined(__STD_C) && _std_proto 41 # define __STD_C 1 42 #endif 43 #if !defined(__STD_C) 44 # define __STD_C 0 45 #endif 46 47 /* extern symbols must be protected against C++ name mangling */ 48 #ifndef _BEGIN_EXTERNS_ 49 # if __cplusplus || c_plusplus 50 # define _BEGIN_EXTERNS_ extern "C" { 51 # define _END_EXTERNS_ } 52 # else 53 # define _BEGIN_EXTERNS_ 54 # define _END_EXTERNS_ 55 # endif 56 #endif 57 58 /* _ARG_ simplifies function prototyping among flavors of C */ 59 #ifndef _ARG_ 60 # if __STD_C 61 # define _ARG_(x) x 62 # else 63 # define _ARG_(x) () 64 # endif 65 #endif 66 67 /* _NIL_ simplifies defining nil pointers to a given type */ 68 #ifndef _NIL_ 69 # define _NIL_(x) ((x)0) 70 #endif 71 72 /* __INLINE__, if defined, is the inline keyword */ 73 #if !defined(__INLINE__) && defined(__cplusplus) 74 # define __INLINE__ inline 75 #endif 76 #if !defined(__INLINE__) && defined(_WIN32) && !defined(__GNUC__) 77 # define __INLINE__ __inline 78 #endif 79 80 /* Void_t is defined so that Void_t* can address any type */ 81 #ifndef Void_t 82 # if __STD_C 83 # define Void_t void 84 # else 85 # define Void_t char 86 # endif 87 #endif 88 89 /* windows variants and veneers */ 90 #if !defined(_WINIX) && (_UWIN || __CYGWIN__ || __EMX__) 91 # define _WINIX 1 92 #endif 93 94 /* dynamic linked library external scope handling */ 95 #ifdef __DYNAMIC__ 96 # undef __DYNAMIC__ 97 # ifndef _DLL 98 # define _DLL 1 99 # endif 100 #endif 101 #if _dll_import 102 # if _BLD_STATIC && !_BLD_DLL 103 # undef _DLL 104 # else 105 # if !_UWIN && !defined(_DLL) 106 # define _DLL 1 107 # endif 108 # endif 109 # if !defined(__EXPORT__) && _BLD_DLL 110 # define __EXPORT__ __declspec(dllexport) 111 # endif 112 # if !defined(__IMPORT__) && ( _BLD_DLL || defined(_DLL) ) 113 # define __IMPORT__ __declspec(dllimport) 114 # endif 115 # if _BLD_DLL && _UWIN 116 # define __DYNAMIC__(v) (_ast_getdll()->_ast_ ## v) 117 # endif 118 #endif 119 #if !defined(_astimport) 120 # if defined(__IMPORT__) && defined(_DLL) 121 # define _astimport __IMPORT__ 122 # else 123 # define _astimport extern 124 # endif 125 #endif 126 #if _dll_import && ( !_BLD_DLL || _WINIX && !_UWIN ) 127 # ifdef __STDC__ 128 # define __EXTERN__(T,obj) extern T obj; T* _imp__ ## obj = &obj 129 # define __DEFINE__(T,obj,val) T obj = val; T* _imp__ ## obj = &obj 130 # else 131 # define __EXTERN__(T,obj) extern T obj; T* _imp__/**/obj = &obj 132 # define __DEFINE__(T,obj,val) T obj = val; T* _imp__/**/obj = &obj 133 # endif 134 #else 135 # define __EXTERN__(T,obj) extern T obj 136 # define __DEFINE__(T,obj,val) T obj = val 137 #endif 138}end 139 140if tst - note{ <stdarg.h>+<wchar.h> works }end compile{ 141 /*<NOSTDIO>*/ 142 #include <stdarg.h> 143 #include <wchar.h> 144 }end 145elif tst - note{ explicit <sys/va_list.h> before <stdarg.h>+<wchar.h> }end compile{ 146 /*<NOSTDIO>*/ 147 #include <sys/va_list.h> 148 #include <stdarg.h> 149 #include <wchar.h> 150 }end { 151 #include <sys/va_list.h> 152 } 153endif 154 155tst ast_LL note{ LL numeric suffix supported }end compile{ 156 int i = 1LL; 157 unsigned int u = 1ULL; /* NOTE: some compilers choke on 1LLU */ 158}end 159 160tst - -DN=1 - -DN=2 - -DN=3 - -DN=4 - -DN=5 - -DN=6 - -DN=7 - -DN=8 - -DN=0 output{ 161 #define _BYTESEX_H 162 163 #include <string.h> 164 #include <sys/types.h> 165 166 #if _STD_ 167 #if N == 1 168 #define _ast_int8_t long 169 #define _ast_int8_str "long" 170 #endif 171 #if N == 2 172 #define _ast_int8_t long long 173 #define _ast_int8_str "long long" 174 #endif 175 #if N == 3 176 #define _ast_int8_t __int64 177 #define _ast_int8_str "__int64" 178 #endif 179 #if N == 4 180 #define _ast_int8_t __int64_t 181 #define _ast_int8_str "__int64_t" 182 #endif 183 #if N == 5 184 #define _ast_int8_t _int64_t 185 #define _ast_int8_str "_int64_t" 186 #endif 187 #if N == 6 188 #define _ast_int8_t int64_t 189 #define _ast_int8_str "int64_t" 190 #endif 191 #if N == 7 192 #define _ast_int8_t _int64 193 #define _ast_int8_str "_int64" 194 #endif 195 #if N == 8 196 #define _ast_int8_t int64 197 #define _ast_int8_str "int64" 198 #endif 199 #endif 200 201 #define elementsof(x) (sizeof(x)/sizeof(x[0])) 202 203 static char i_char = 1; 204 static short i_short = 1; 205 static int i_int = 1; 206 static long i_long = 1L; 207 #ifdef _ast_int8_t 208 #if _ast_LL 209 static _ast_int8_t i_long_long = 1LL; 210 static unsigned _ast_int8_t u_long_long = 18446744073709551615ULL; 211 #else 212 static _ast_int8_t i_long_long = 1; 213 static unsigned _ast_int8_t u_long_long = 18446744073709551615; 214 #endif 215 #endif 216 217 static struct 218 { 219 char* name; 220 int size; 221 char* swap; 222 } int_type[] = 223 { 224 "char", sizeof(char), (char*)&i_char, 225 "short", sizeof(short), (char*)&i_short, 226 "int", sizeof(int), (char*)&i_int, 227 "long", sizeof(long), (char*)&i_long, 228 #ifdef _ast_int8_t 229 _ast_int8_str, sizeof(_ast_int8_t), (char*)&i_long_long, 230 #endif 231 }; 232 233 static int int_size[] = { 1, 2, 4, 8 }; 234 235 int 236 main() 237 { 238 register int t; 239 register int s; 240 register int m = 1; 241 register int b = 1; 242 register int w = 0; 243 244 #ifdef _ast_int8_t 245 unsigned _ast_int8_t p; 246 char buf[64]; 247 248 if (int_type[elementsof(int_type)-1].size <= 4) 249 return 1; 250 p = 0x12345678; 251 p <<= 32; 252 p |= 0x9abcdef0; 253 sprintf(buf, "0x%016llx", p); 254 if (strcmp(buf, "0x123456789abcdef0")) 255 return 1; 256 #endif 257 for (s = 0; s < elementsof(int_size); s++) 258 { 259 for (t = 0; t < elementsof(int_type) && int_type[t].size < int_size[s]; t++); 260 if (t < elementsof(int_type)) 261 { 262 m = int_size[s]; 263 #if __INTERIX 264 if (m == 8) 265 { 266 printf("#ifdef _MSC_VER\n"); 267 printf("#define _ast_int8_t __int64\n"); 268 printf("#else\n"); 269 printf("#define _ast_int8_t long long\n"); 270 printf("#endif\n"); 271 } 272 else 273 #endif 274 printf("#define _ast_int%d_t %s\n", m, int_type[t].name); 275 if (m > 1) 276 { 277 if (*int_type[t].swap) 278 w |= b; 279 b <<= 1; 280 } 281 } 282 } 283 printf("#define _ast_intmax_t _ast_int%d_t\n", m); 284 if (m == sizeof(long)) 285 printf("#define _ast_intmax_long 1\n"); 286 printf("#define _ast_intswap %d\n", w); 287 printf("\n"); 288 printf("#define _ast_sizeof_intmax_t %d /* sizeof(intmax_t) */\n", m); 289 return 0; 290 } 291}end 292 293tst - output{ 294 #include <string.h> 295 #include <sys/types.h> 296 297 #if _X86_ || _X64_ 298 #define COND 1 299 #define CONDNAME "_X64_" 300 #else 301 #define COND 0 302 #endif 303 304 #define elementsof(x) (sizeof(x)/sizeof(x[0])) 305 306 static struct 307 { 308 char* name; 309 int size; 310 int cond; 311 } types[] = 312 { 313 "short", sizeof(short), 0, 314 "int", sizeof(int), 0, 315 "long", sizeof(long), 0, 316 "size_t", sizeof(size_t), 0, 317 "off_t", sizeof(off_t), 0, 318 "pointer", sizeof(void*), COND * 4, 319 "float", sizeof(float), 0, 320 "double", sizeof(double), 0, 321 #ifdef _typ_long_double 322 "long_double", sizeof(long double), 0, 323 #endif 324 }; 325 326 int 327 main() 328 { 329 register int t; 330 331 for (t = 0; t < elementsof(types); t++) 332 #if COND 333 if (types[t].cond) 334 { 335 printf("#if %s\n", CONDNAME); 336 printf("#define _ast_sizeof_%s%s %d /* sizeof(%s) */\n", types[t].name, strlen(types[t].name) < 4 ? "\t" : "", types[t].cond * 2, types[t].name); 337 printf("#else\n"); 338 printf("#define _ast_sizeof_%s%s %d /* sizeof(%s) */\n", types[t].name, strlen(types[t].name) < 4 ? "\t" : "", types[t].cond, types[t].name); 339 printf("#endif\n"); 340 } 341 else 342 #endif 343 printf("#define _ast_sizeof_%s%s %d /* sizeof(%s) */\n", types[t].name, strlen(types[t].name) < 4 ? "\t" : "", types[t].size, types[t].name); 344 printf("\n"); 345 return 0; 346 } 347}end 348 349tst - -DN=1 - -DN=0 output{ 350 #define _BYTESEX_H 351 352 #include <string.h> 353 #include <sys/types.h> 354 355 #if !N || !_STD_ 356 #undef _typ_long_double 357 #endif 358 359 #define elementsof(x) (sizeof(x)/sizeof(x[0])) 360 361 static struct 362 { 363 char* name; 364 int size; 365 } flt_type[] = 366 { 367 "float", sizeof(float), 368 "double", sizeof(double), 369 #ifdef _typ_long_double 370 "long double", sizeof(long double), 371 #endif 372 }; 373 374 int 375 main() 376 { 377 register int t; 378 register int m = 1; 379 380 #ifdef _typ_long_double 381 long double p; 382 char buf[64]; 383 384 if (flt_type[elementsof(flt_type)-1].size <= sizeof(double)) 385 return 1; 386 p = 1.12345E-55; 387 sprintf(buf, "%1.5LE", p); 388 if (strcmp(buf, "1.12345E-55")) 389 return 1; 390 #endif 391 for (t = 0; t < elementsof(flt_type); t++) 392 { 393 while (t < (elementsof(flt_type) - 1) && flt_type[t].size == flt_type[t + 1].size) 394 t++; 395 m = flt_type[t].size; 396 printf("#define _ast_flt%d_t %s\n", flt_type[t].size, flt_type[t].name); 397 } 398 printf("#define _ast_fltmax_t _ast_flt%d_t\n", m); 399 if (m == sizeof(double)) 400 printf("#define _ast_fltmax_double 1\n"); 401 return 0; 402 } 403}end 404 405typ int8_t stdint.h inttypes.h no{ 406 #undef _typ_int8_t 407 #define _typ_int8_t 1 408 typedef _ast_int1_t int8_t; 409}end 410typ uint8_t stdint.h inttypes.h no{ 411 #undef _typ_uint8_t 412 #define _typ_uint8_t 1 413 typedef unsigned _ast_int1_t uint8_t; 414}end 415typ int16_t stdint.h inttypes.h no{ 416 #undef _typ_int16_t 417 #define _typ_int16_t 1 418 typedef _ast_int2_t int16_t; 419}end 420typ uint16_t stdint.h inttypes.h no{ 421 #undef _typ_uint16_t 422 #define _typ_uint16_t 1 423 typedef unsigned _ast_int2_t uint16_t; 424}end 425typ int32_t stdint.h inttypes.h no{ 426 #undef _typ_int32_t 427 #define _typ_int32_t 1 428 typedef _ast_int4_t int32_t; 429}end 430typ uint32_t stdint.h inttypes.h no{ 431 #undef _typ_uint32_t 432 #define _typ_uint32_t 1 433 typedef unsigned _ast_int4_t uint32_t; 434}end 435typ int64_t stdint.h inttypes.h no{ 436 #ifdef _ast_int8_t 437 #undef _typ_int64_t 438 #define _typ_int64_t 1 439 typedef _ast_int8_t int64_t; 440 #endif 441}end 442typ uint64_t stdint.h inttypes.h no{ 443 #ifdef _ast_int8_t 444 #undef _typ_uint64_t 445 #define _typ_uint64_t 1 446 typedef unsigned _ast_int8_t uint64_t; 447 #endif 448}end 449typ intmax_t stdint.h inttypes.h no{ 450 #undef _typ_intmax_t 451 #define _typ_intmax_t 1 452 typedef _ast_intmax_t intmax_t; 453}end 454typ uintmax_t stdint.h inttypes.h no{ 455 #undef _typ_uintmax_t 456 #define _typ_uintmax_t 1 457 typedef unsigned _ast_intmax_t uintmax_t; 458}end 459typ uintptr_t stdint.h inttypes.h no{ 460 #undef _typ_uintptr_t 461 #define _typ_uintptr_t 1 462 #if _ast_sizeof_pointer == 8 && defined(_ast_int8_t) 463 typedef unsigned _ast_int8_t uintptr_t; 464 #else 465 typedef unsigned _ast_int4_t uintptr_t; 466 #endif 467}end 468typ _Bool = uint8_t 469cat{ 470 #if defined(_STDC_C99) || __STDC_VERSION__ >= 199901L 471 #include <stdbool.h> 472 #else 473 #define bool _Bool 474 #define false 0 475 #define true 1 476 #endif 477}end 478if tst key___thread -lpthread note{ __thread keyword exists and works with -lpthread }end execute{ 479 #if defined(__APPLE__) || defined(__APPLE_CC__) || defined(__MACH__) 480 ( /* __thread does not work in dlls */ 481 #endif 482 483 #include <pthread.h> 484 485 #define INITIAL 1 486 #define LOOP 100 487 488 static __thread int specific = INITIAL; 489 static int global = 0; 490 491 static void* worker(void* arg) 492 { 493 int k; 494 int v; 495 v = (int)(arg - 0); 496 for (k = 0; k < LOOP; ++k) 497 { 498 specific += v; 499 usleep(1); 500 } 501 if (specific != (INITIAL + LOOP * v)) 502 global = 1; 503 return 0; 504 } 505 int main() 506 { 507 pthread_t th[2]; 508 509 if (pthread_create(&th[0], 0, worker, (void*)0 + 5) || 510 pthread_create(&th[1], 0, worker, (void*)0 + 7)) 511 { 512 NOTE("pthread_create failed"); 513 return 1; 514 } 515 pthread_join(th[0], 0); 516 pthread_join(th[1], 0); 517 if (global) 518 { 519 NOTE("__thread variable not thread specific"); 520 return 1; 521 } 522 if (specific != INITIAL) 523 { 524 NOTE("main __thread variable changed by another thread"); 525 return 1; 526 } 527 return 0; 528 } 529 }end 530elif tst - note{ msvc __declspec(thread) works }end compile{ 531 __declspec(thread) tls = 1; 532 }end 533else cat{ 534 #define __thread /* __thread keyword does not exist or does not work with -lpthread */ 535 }end 536endif 537 538tst - -DTRY=1 - -DTRY=1 -Dvoid=char - -DTRY=2 - -DTRY=3 - -DTRY=4 output{ 539 #if _STD_ && _hdr_stdarg 540 #include <stdarg.h> 541 static void 542 varyfunny(int* p, ...) 543 { 544 va_list ap; 545 va_start(ap, p); 546 #if TRY == 1 547 *p = *ap++ != 0; 548 #endif /*TRY == 1*/ 549 #if TRY == 2 550 *p = *ap != 0; 551 #endif /*TRY == 2*/ 552 #if TRY == 3 553 *p = ap++ != 0; 554 #endif /*TRY == 3*/ 555 va_end(ap); 556 } 557 #else 558 #include <varargs.h> 559 static void 560 varyfunny(va_alist) 561 va_dcl 562 { 563 va_list ap; 564 int* p; 565 va_start(ap); 566 p = va_arg(ap, int*); 567 #if TRY == 1 568 *p = *ap++ != 0; 569 #endif /*TRY == 1*/ 570 #if TRY == 2 571 *p = *ap != 0; 572 #endif /*TRY == 2*/ 573 #if TRY == 3 574 *p = ap++ != 0; 575 #endif /*TRY == 3*/ 576 va_end(ap); 577 } 578 #endif 579 int 580 main() 581 { 582 int r; 583 584 printf("\n#ifndef va_listref\n"); 585 printf("#ifndef va_start\n"); 586 printf("#if __STD_C\n"); 587 printf("#include <stdarg.h>\n"); 588 printf("#else\n"); 589 printf("#include <varargs.h>\n"); 590 printf("#endif\n"); 591 printf("#endif\n"); 592 #if TRY == 4 593 printf("#define va_listref(p) (&(p))\t"); 594 printf("/* pass va_list to varargs function */\n"); 595 printf("#define va_listval(p) (*(p))\t"); 596 printf("/* retrieve va_list from va_arg(ap,va_listarg) */\n"); 597 printf("#define va_listarg va_list*\t"); 598 printf("/* va_arg() va_list type */\n"); 599 #else 600 varyfunny(&r); 601 printf("#define va_listref(p) (p)\t"); 602 printf("/* pass va_list to varargs function */\n"); 603 if (sizeof(va_list) > sizeof(void*)) 604 printf("#define va_listval(p) (*(p))\t"); 605 else 606 printf("#define va_listval(p) (p)\t"); 607 printf("/* retrieve va_list from va_arg(ap,va_listarg) */\n"); 608 #if TRY == 2 609 printf("#define va_listarg va_list*\t"); 610 #else 611 printf("#define va_listarg va_list\t"); 612 #endif /*TRY == 2*/ 613 printf("/* va_arg() va_list type */\n"); 614 #endif /*TRY == 4*/ 615 616 #if _UWIN 617 printf("#ifndef va_copy\n"); 618 printf("#define va_copy(to,fr) ((to)=(fr))\t"); 619 printf("/* copy va_list fr -> to */\n"); 620 printf("#endif\n"); 621 #else 622 #if !defined(va_copy) 623 #if defined(__va_copy) 624 printf("#ifndef va_copy\n"); 625 printf("#define va_copy(to,fr) __va_copy(to,fr)\t"); 626 printf("/* copy va_list fr -> to */\n"); 627 printf("#endif\n"); 628 #else 629 #if TRY == 2 630 printf("#ifndef va_copy\n"); 631 printf("#define va_copy(to,fr) memcpy(to,fr,sizeof(va_list))\t"); 632 printf("/* copy va_list fr -> to */\n"); 633 printf("#endif\n"); 634 #else 635 printf("#ifndef va_copy\n"); 636 printf("#define va_copy(to,fr) ((to)=(fr))\t"); 637 printf("/* copy va_list fr -> to */\n"); 638 printf("#endif\n"); 639 #endif 640 #endif 641 #endif 642 #endif 643 644 printf("#endif\n"); 645 return 0; 646 } 647}end 648 649cat{ 650 #ifndef _AST_STD_H 651 # if __STD_C && _hdr_stddef 652 # include <stddef.h> 653 # endif 654 # if _sys_types 655 # include <sys/types.h> 656 # endif 657 # if _hdr_stdint 658 # include <stdint.h> 659 # else 660 # if _hdr_inttypes 661 # include <inttypes.h> 662 # endif 663 # endif 664 #endif 665 #if !_typ_size_t 666 # define _typ_size_t 1 667 typedef int size_t; 668 #endif 669 #if !_typ_ssize_t 670 # define _typ_ssize_t 1 671 typedef int ssize_t; 672 #endif 673 #ifndef _AST_STD_H 674 # define _def_map_ast 1 675 # if !_def_map_ast 676 # include <ast_map.h> 677 # endif 678 #endif 679}end 680 681run{ 682 grep __NO_INCLUDE_WARN__ /usr/include/stat.h >/dev/null 2>&1 && 683 grep '<name.h>' /usr/include/sys/stat.h >/dev/null 2>&1 && 684 grep __name_h /usr/include/name.h >/dev/null 2>&1 && 685 cat <<! 686 /* disable ${HOSTTYPE} <sys/foo.h> vs. <foo.h> clash warnings */ 687 #ifndef __NO_INCLUDE_WARN__ 688 #define __NO_INCLUDE_WARN__ 1 689 #endif 690 /* disable ${HOSTTYPE} <sys/stat.h> <name.h> hijack */ 691 #ifndef __name_h 692 #define __name_h 1 693 #endif 694 ! 695}end 696