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		return 0;
289	}
290}end
291
292tst	- output{
293	#include <string.h>
294	#include <sys/types.h>
295
296	#if _X86_ || _X64_
297	#define COND		1
298	#define CONDNAME	"_X64_"
299	#else
300	#define COND		0
301	#endif
302
303	#define elementsof(x)	(sizeof(x)/sizeof(x[0]))
304
305	static struct
306	{
307		char*	name;
308		int	size;
309		int	cond;
310	} types[] =
311	{
312		"short",	sizeof(short),		0,
313		"int",		sizeof(int),		0,
314		"long",		sizeof(long),		0,
315		"size_t",	sizeof(size_t),		0,
316		"pointer",	sizeof(void*),		COND * 4,
317		"float",	sizeof(float),		0,
318		"double",	sizeof(double),		0,
319	#ifdef _typ_long_double
320		"long_double",	sizeof(long double),	0,
321	#endif
322	};
323
324	int
325	main()
326	{
327		register int	t;
328
329		for (t = 0; t < elementsof(types); t++)
330	#if COND
331			if (types[t].cond)
332			{
333				printf("#if %s\n", CONDNAME);
334				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);
335				printf("#else\n");
336				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);
337				printf("#endif\n");
338			}
339			else
340	#endif
341				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);
342		printf("\n");
343		return 0;
344	}
345}end
346
347tst	- -DN=1 - -DN=0 output{
348	#define _BYTESEX_H
349
350	#include <string.h>
351	#include <sys/types.h>
352
353	#if !N || !_STD_
354	#undef	_typ_long_double
355	#endif
356
357	#define elementsof(x)	(sizeof(x)/sizeof(x[0]))
358
359	static struct
360	{
361		char*	name;
362		int	size;
363	} flt_type[] =
364	{
365		"float",	sizeof(float),
366		"double",	sizeof(double),
367	#ifdef _typ_long_double
368		"long double",	sizeof(long double),
369	#endif
370	};
371
372	int
373	main()
374	{
375		register int	t;
376		register int	m = 1;
377
378	#ifdef _typ_long_double
379		long double	p;
380		char		buf[64];
381
382		if (flt_type[elementsof(flt_type)-1].size <= sizeof(double))
383			return 1;
384		p = 1.12345E-55;
385		sprintf(buf, "%1.5LE", p);
386		if (strcmp(buf, "1.12345E-55"))
387			return 1;
388	#endif
389		for (t = 0; t < elementsof(flt_type); t++)
390		{
391			while (t < (elementsof(flt_type) - 1) && flt_type[t].size == flt_type[t + 1].size)
392				t++;
393			m = flt_type[t].size;
394			printf("#define _ast_flt%d_t		%s\n", flt_type[t].size, flt_type[t].name);
395		}
396		printf("#define _ast_fltmax_t		_ast_flt%d_t\n", m);
397		if (m == sizeof(double))
398			printf("#define _ast_fltmax_double		1\n");
399		return 0;
400	}
401}end
402
403typ int8_t stdint.h inttypes.h no{
404	#undef	_typ_int8_t
405	#define	_typ_int8_t	1
406	typedef _ast_int1_t int8_t;
407}end
408typ uint8_t stdint.h inttypes.h no{
409	#undef	_typ_uint8_t
410	#define	_typ_uint8_t	1
411	typedef unsigned _ast_int1_t uint8_t;
412}end
413typ int16_t stdint.h inttypes.h no{
414	#undef	_typ_int16_t
415	#define	_typ_int16_t	1
416	typedef _ast_int2_t int16_t;
417}end
418typ uint16_t stdint.h inttypes.h no{
419	#undef	_typ_uint16_t
420	#define	_typ_uint16_t	1
421	typedef unsigned _ast_int2_t uint16_t;
422}end
423typ int32_t stdint.h inttypes.h no{
424	#undef	_typ_int32_t
425	#define	_typ_int32_t	1
426	typedef _ast_int4_t int32_t;
427}end
428typ uint32_t stdint.h inttypes.h no{
429	#undef	_typ_uint32_t
430	#define	_typ_uint32_t	1
431	typedef unsigned _ast_int4_t uint32_t;
432}end
433typ int64_t stdint.h inttypes.h no{
434	#ifdef _ast_int8_t
435	#undef	_typ_int64_t
436	#define	_typ_int64_t	1
437	typedef _ast_int8_t int64_t;
438	#endif
439}end
440typ uint64_t stdint.h inttypes.h no{
441	#ifdef _ast_int8_t
442	#undef	_typ_uint64_t
443	#define	_typ_uint64_t	1
444	typedef unsigned _ast_int8_t uint64_t;
445	#endif
446}end
447typ intmax_t stdint.h inttypes.h no{
448	#undef	_typ_intmax_t
449	#define	_typ_intmax_t	1
450	typedef _ast_intmax_t intmax_t;
451}end
452typ uintmax_t stdint.h inttypes.h no{
453	#undef	_typ_uintmax_t
454	#define	_typ_uintmax_t	1
455	typedef unsigned _ast_intmax_t uintmax_t;
456}end
457typ uintptr_t stdint.h inttypes.h no{
458	#undef	_typ_uintptr_t
459	#define	_typ_uintptr_t	1
460	#if _ast_sizeof_pointer == 8 && defined(_ast_int8_t)
461	typedef unsigned _ast_int8_t uintptr_t;
462	#else
463	typedef unsigned _ast_int4_t uintptr_t;
464	#endif
465}end
466
467tst	- -DTRY=1 - -DTRY=1 -Dvoid=char - -DTRY=2 - -DTRY=3 - -DTRY=4 output{
468	#if _STD_ && _hdr_stdarg
469	#include <stdarg.h>
470	static void
471	varyfunny(int* p, ...)
472	{
473		va_list	ap;
474		va_start(ap, p);
475	#if TRY == 1
476		*p = *ap++ != 0;
477	#endif /*TRY == 1*/
478	#if TRY == 2
479		*p = *ap != 0;
480	#endif /*TRY == 2*/
481	#if TRY == 3
482		*p = ap++ != 0;
483	#endif /*TRY == 3*/
484		va_end(ap);
485	}
486	#else
487	#include <varargs.h>
488	static void
489	varyfunny(va_alist)
490	va_dcl
491	{
492		va_list	ap;
493		int*	p;
494		va_start(ap);
495		p = va_arg(ap, int*);
496	#if TRY == 1
497		*p = *ap++ != 0;
498	#endif /*TRY == 1*/
499	#if TRY == 2
500		*p = *ap != 0;
501	#endif /*TRY == 2*/
502	#if TRY == 3
503		*p = ap++ != 0;
504	#endif /*TRY == 3*/
505		va_end(ap);
506	}
507	#endif
508	int
509	main()
510	{
511		int	r;
512
513		printf("\n#ifndef va_listref\n");
514		printf("#ifndef	va_start\n");
515		printf("#if __STD_C\n");
516		printf("#include <stdarg.h>\n");
517		printf("#else\n");
518		printf("#include <varargs.h>\n");
519		printf("#endif\n");
520		printf("#endif\n");
521	#if TRY == 4
522		printf("#define va_listref(p) (&(p))\t");
523			printf("/* pass va_list to varargs function */\n");
524		printf("#define va_listval(p) (*(p))\t");
525			printf("/* retrieve va_list from va_arg(ap,va_listarg) */\n");
526		printf("#define va_listarg va_list*\t");
527			printf("/* va_arg() va_list type */\n");
528	#else
529		varyfunny(&r);
530		printf("#define va_listref(p) (p)\t");
531			printf("/* pass va_list to varargs function */\n");
532		if (sizeof(va_list) > sizeof(void*))
533			printf("#define va_listval(p) (*(p))\t");
534		else
535			printf("#define va_listval(p) (p)\t");
536			printf("/* retrieve va_list from va_arg(ap,va_listarg) */\n");
537	#if TRY == 2
538		printf("#define va_listarg va_list*\t");
539	#else
540		printf("#define va_listarg va_list\t");
541	#endif /*TRY == 2*/
542			printf("/* va_arg() va_list type */\n");
543	#endif /*TRY == 4*/
544
545	#if _UWIN
546		printf("#ifndef va_copy\n");
547		printf("#define va_copy(to,fr) ((to)=(fr))\t");
548			printf("/* copy va_list fr -> to */\n");
549		printf("#endif\n");
550	#else
551	#if !defined(va_copy)
552	#if defined(__va_copy)
553		printf("#ifndef va_copy\n");
554		printf("#define va_copy(to,fr) __va_copy(to,fr)\t");
555			printf("/* copy va_list fr -> to */\n");
556		printf("#endif\n");
557	#else
558	#if TRY == 2
559		printf("#ifndef va_copy\n");
560		printf("#define va_copy(to,fr) memcpy(to,fr,sizeof(va_list))\t");
561			printf("/* copy va_list fr -> to */\n");
562		printf("#endif\n");
563	#else
564		printf("#ifndef va_copy\n");
565		printf("#define va_copy(to,fr) ((to)=(fr))\t");
566			printf("/* copy va_list fr -> to */\n");
567		printf("#endif\n");
568	#endif
569	#endif
570	#endif
571	#endif
572
573		printf("#endif\n");
574		return 0;
575	}
576}end
577
578cat{
579	#ifndef _AST_STD_H
580	#	if __STD_C && _hdr_stddef
581	#	include	<stddef.h>
582	#	endif
583	#	if _sys_types
584	#	include	<sys/types.h>
585	#	endif
586	#	if _hdr_stdint
587	#	include	<stdint.h>
588	#	else
589	#		if _hdr_inttypes
590	#		include	<inttypes.h>
591	#		endif
592	#	endif
593	#endif
594	#if !_typ_size_t
595	#	define _typ_size_t	1
596		typedef int size_t;
597	#endif
598	#if !_typ_ssize_t
599	#	define _typ_ssize_t	1
600		typedef int ssize_t;
601	#endif
602	#ifndef _AST_STD_H
603	#	define _def_map_ast	1
604	#	if !_def_map_ast
605	#		include <ast_map.h>
606	#	endif
607	#endif
608}end
609
610run{
611	grep __NO_INCLUDE_WARN__ /usr/include/stat.h >/dev/null 2>&1 &&
612	grep '<name.h>' /usr/include/sys/stat.h >/dev/null 2>&1 &&
613	grep __name_h /usr/include/name.h >/dev/null 2>&1 &&
614	cat <<!
615	/* disable ${HOSTTYPE} <sys/foo.h> vs. <foo.h> clash warnings */
616	#ifndef __NO_INCLUDE_WARN__
617	#define __NO_INCLUDE_WARN__	1
618	#endif
619	/* disable ${HOSTTYPE} <sys/stat.h> <name.h> hijack */
620	#ifndef __name_h
621	#define __name_h		1
622	#endif
623	!
624}end
625