OSDN Git Service

import nethack-3.6.0
[jnethack/source.git] / include / tradstdc.h
1 /* NetHack 3.6  tradstdc.h      $NHDT-Date: 1448210011 2015/11/22 16:33:31 $  $NHDT-Branch: master $:$NHDT-Revision: 1.27 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /* NetHack may be freely redistributed.  See license for details. */
4
5 #ifndef TRADSTDC_H
6 #define TRADSTDC_H
7
8 #if defined(DUMB) && !defined(NOVOID)
9 #define NOVOID
10 #endif
11
12 #ifdef NOVOID
13 #define void int
14 #endif
15
16 /*
17  * Borland C provides enough ANSI C compatibility in its Borland C++
18  * mode to warrant this.  But it does not set __STDC__ unless it compiles
19  * in its ANSI keywords only mode, which prevents use of <dos.h> and
20  * far pointer use.
21  */
22 #if (defined(__STDC__) || defined(__TURBOC__)) && !defined(NOTSTDC)
23 #define NHSTDC
24 #endif
25
26 #if defined(ultrix) && defined(__STDC__) && !defined(__LANGUAGE_C)
27 /* Ultrix seems to be in a constant state of flux.  This check attempts to
28  * set up ansi compatibility if it wasn't set up correctly by the compiler.
29  */
30 #ifdef mips
31 #define __mips mips
32 #endif
33 #ifdef LANGUAGE_C
34 #define __LANGUAGE_C LANGUAGE_C
35 #endif
36 #endif
37
38 /*
39  * ANSI X3J11 detection.
40  * Makes substitutes for compatibility with the old C standard.
41  */
42
43 /* Decide how to handle variable parameter lists:
44  * USE_STDARG means use the ANSI <stdarg.h> facilities (only ANSI compilers
45  * should do this, and only if the library supports it).
46  * USE_VARARGS means use the <varargs.h> facilities.  Again, this should only
47  * be done if the library supports it.  ANSI is *not* required for this.
48  * Otherwise, the kludgy old methods are used.
49  * The defaults are USE_STDARG for ANSI compilers, and USE_OLDARGS for
50  * others.
51  */
52
53 /* #define USE_VARARGS */ /* use <varargs.h> instead of <stdarg.h> */
54 /* #define USE_OLDARGS */ /* don't use any variable argument facilities */
55
56 #if defined(apollo) /* Apollos have stdarg(3) but not stdarg.h */
57 #define USE_VARARGS
58 #endif
59
60 #if defined(NHSTDC) || defined(ULTRIX_PROTO) || defined(MAC)
61 #if !defined(USE_VARARGS) && !defined(USE_OLDARGS) && !defined(USE_STDARG)
62 #define USE_STDARG
63 #endif
64 #endif
65
66 #ifdef NEED_VARARGS /* only define these if necessary */
67 /*
68  * These have changed since 3.4.3.  VA_END() now provides an explicit
69  * closing brace to complement VA_DECL()'s hidden opening brace, so code
70  * started with VA_DECL() needs an extra opening brace to complement
71  * the explicit final closing brace.  This was done so that the source
72  * would look less strange, where VA_DECL() appeared to introduce a
73  * function whose opening brace was missing; there are now visible and
74  * invisible braces at beginning and end.  Sample usage:
75  void foo VA_DECL(int, arg)  --macro expansion has a hidden opening brace
76  {  --new, explicit opening brace (actually introduces a nested block)
77  VA_START(bar);
78  ...code for foo...
79  VA_END();  --expansion now provides a closing brace for the nested block
80  }  --existing closing brace, still pairs with the hidden one in VA_DECL()
81  * Reading the code--or using source browsing tools which match braces--
82  * results in seeing a matched set of braces.  Usage of VA_END() is
83  * potentially trickier, but nethack uses it in a straightforward manner.
84  */
85
86 #ifdef USE_STDARG
87 #include <stdarg.h>
88 #define VA_DECL(typ1, var1) \
89     (typ1 var1, ...)        \
90     {                       \
91         va_list the_args;
92 #define VA_DECL2(typ1, var1, typ2, var2) \
93     (typ1 var1, typ2 var2, ...)          \
94     {                                    \
95         va_list the_args;
96 #define VA_INIT(var1, typ1)
97 #define VA_NEXT(var1, typ1) var1 = va_arg(the_args, typ1)
98 #define VA_ARGS the_args
99 #define VA_START(x) va_start(the_args, x)
100 #define VA_END()      \
101     va_end(the_args); \
102     }
103 #if defined(ULTRIX_PROTO) && !defined(_VA_LIST_)
104 #define _VA_LIST_ /* prevents multiple def in stdio.h */
105 #endif
106 #else
107
108 #ifdef USE_VARARGS
109 #include <varargs.h>
110 #define VA_DECL(typ1, var1) \
111     (va_alist) va_dcl       \
112     {                       \
113         va_list the_args;   \
114         typ1 var1;
115 #define VA_DECL2(typ1, var1, typ2, var2) \
116     (va_alist) va_dcl                    \
117     {                                    \
118         va_list the_args;                \
119         typ1 var1;                       \
120         typ2 var2;
121 #define VA_ARGS the_args
122 #define VA_START(x) va_start(the_args)
123 #define VA_INIT(var1, typ1) var1 = va_arg(the_args, typ1)
124 #define VA_NEXT(var1, typ1) var1 = va_arg(the_args, typ1)
125 #define VA_END()      \
126     va_end(the_args); \
127     }
128 #else
129
130 /*USE_OLDARGS*/
131 #define VA_ARGS arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9
132 #define VA_DECL(typ1, var1)                                             \
133     (var1, VA_ARGS) typ1 var1;                                          \
134     char *arg1, *arg2, *arg3, *arg4, *arg5, *arg6, *arg7, *arg8, *arg9; \
135     {
136 #define VA_DECL2(typ1, var1, typ2, var2)                                \
137     (var1, var2, VA_ARGS) typ1 var1;                                    \
138     typ2 var2;                                                          \
139     char *arg1, *arg2, *arg3, *arg4, *arg5, *arg6, *arg7, *arg8, *arg9; \
140     {
141 #define VA_START(x)
142 #define VA_INIT(var1, typ1)
143 /* This is inherently risky, and should only be attempted as a
144    very last resort; manipulating arguments which haven't actually
145    been passed may or may not cause severe trouble depending on
146    the function-calling/argument-passing mechanism being used.
147
148    [nethack's core doesn't use VA_NEXT() so doesn't use VA_SHIFT()
149    either, and this definition is just retained for completeness.
150    lev_comp does use VA_NEXT(), but it passes all 'argX' arguments.]
151  */
152 #define VA_SHIFT()                                                    \
153     (arg1 = arg2, arg2 = arg3, arg3 = arg4, arg4 = arg5, arg5 = arg6, \
154      arg6 = arg7, arg7 = arg8, arg8 = arg9)
155 #define VA_NEXT(var1, typ1) ((var1 = (typ1) arg1), VA_SHIFT(), var1)
156 #define VA_END() }
157 #endif
158 #endif
159
160 #endif /* NEED_VARARGS */
161
162 #if defined(NHSTDC) || defined(MSDOS) || defined(MAC) \
163     || defined(ULTRIX_PROTO) || defined(__BEOS__)
164
165 /*
166  * Used for robust ANSI parameter forward declarations:
167  * int VDECL(sprintf, (char *, const char *, ...));
168  *
169  * NDECL() is used for functions with zero arguments;
170  * FDECL() is used for functions with a fixed number of arguments;
171  * VDECL() is used for functions with a variable number of arguments.
172  * Separate macros are needed because ANSI will mix old-style declarations
173  * with prototypes, except in the case of varargs, and the OVERLAY-specific
174  * trampoli.* mechanism conflicts with the ANSI <<f(void)>> syntax.
175  */
176
177 #define NDECL(f) f(void) /* overridden later if USE_TRAMPOLI set */
178
179 #define FDECL(f, p) f p
180
181 #if defined(MSDOS) || defined(USE_STDARG)
182 #define VDECL(f, p) f p
183 #else
184 #define VDECL(f, p) f()
185 #endif
186
187 /*
188  * Used for definitions of functions which take no arguments to force
189  * an explicit match with the NDECL prototype.  Needed in some cases
190  * (MS Visual C 2005) for functions called through pointers.
191  */
192 #define VOID_ARGS void
193
194 /* generic pointer, always a macro; genericptr_t is usually a typedef */
195 #define genericptr void *
196
197 #if (defined(ULTRIX_PROTO) && !defined(__GNUC__)) || defined(OS2_CSET2)
198 /* Cover for Ultrix on a DECstation with 2.0 compiler, which coredumps on
199  *   typedef void * genericptr_t;
200  *   extern void a(void(*)(int, genericptr_t));
201  * Using the #define is OK for other compiler versions too.
202  */
203 /* And IBM CSet/2.  The redeclaration of free hoses the compile. */
204 #define genericptr_t genericptr
205 #else
206 #if !defined(NHSTDC) && !defined(MAC)
207 #define const
208 #define signed
209 #define volatile
210 #endif
211 #endif
212
213 /*
214  * Suppress `const' if necessary and not handled elsewhere.
215  * Don't use `#if defined(xxx) && !defined(const)'
216  * because some compilers choke on `defined(const)'.
217  * This has been observed with Lattice, MPW, and High C.
218  */
219 #if (defined(ULTRIX_PROTO) && !defined(NHSTDC)) || defined(apollo)
220 /* the system header files don't use `const' properly */
221 #ifndef const
222 #define const
223 #endif
224 #endif
225
226 #else /* NHSTDC */ /* a "traditional" C  compiler */
227
228 #define NDECL(f) f()
229 #define FDECL(f, p) f()
230 #define VDECL(f, p) f()
231
232 #define VOID_ARGS /*empty*/
233
234 #if defined(AMIGA) || defined(HPUX) || defined(POSIX_TYPES) \
235     || defined(__DECC) || defined(__BORLANDC__)
236 #define genericptr void *
237 #endif
238 #ifndef genericptr
239 #define genericptr char *
240 #endif
241
242 /*
243  * Traditional C compilers don't have "signed", "const", or "volatile".
244  */
245 #define signed
246 #define const
247 #define volatile
248
249 #endif /* NHSTDC */
250
251 #ifndef genericptr_t
252 typedef genericptr genericptr_t; /* (void *) or (char *) */
253 #endif
254
255 #if defined(MICRO) || defined(WIN32)
256 /* We actually want to know which systems have an ANSI run-time library
257  * to know which support the %p format for printing pointers.
258  * Due to the presence of things like gcc, NHSTDC is not a good test.
259  * So we assume microcomputers have all converted to ANSI and bigger
260  * computers which may have older libraries give reasonable results with
261  * casting pointers to unsigned long int (fmt_ptr() in alloc.c).
262  */
263 #define HAS_PTR_FMT
264 #endif
265
266 /*
267  * According to ANSI, prototypes for old-style declarations must widen the
268  * arguments to int.  However, the MSDOS compilers accept shorter arguments
269  * (char, short, etc.) in prototypes and do typechecking with them.  Therefore
270  * this mess to allow the better typechecking while also allowing some
271  * prototypes for the ANSI compilers so people quit trying to fix the
272  * prototypes to match the standard and thus lose the typechecking.
273  */
274 #if defined(MSDOS) && !defined(__GO32__)
275 #define UNWIDENED_PROTOTYPES
276 #endif
277 #if defined(AMIGA) && !defined(AZTEC_50)
278 #define UNWIDENED_PROTOTYPES
279 #endif
280 #if defined(macintosh) && (defined(__SC__) || defined(__MRC__))
281 #define WIDENED_PROTOTYPES
282 #endif
283 #if defined(__MWERKS__) && defined(__BEOS__)
284 #define UNWIDENED_PROTOTYPES
285 #endif
286 #if defined(WIN32)
287 #define UNWIDENED_PROTOTYPES
288 #endif
289
290 #if defined(ULTRIX_PROTO) && defined(ULTRIX_CC20)
291 #define UNWIDENED_PROTOTYPES
292 #endif
293 #if defined(apollo)
294 #define UNWIDENED_PROTOTYPES
295 #endif
296
297 #ifndef UNWIDENED_PROTOTYPES
298 #if defined(NHSTDC) || defined(ULTRIX_PROTO) || defined(THINK_C)
299 #ifndef WIDENED_PROTOTYPES
300 #define WIDENED_PROTOTYPES
301 #endif
302 #endif
303 #endif
304
305 /* These are used for arguments within FDECL/VDECL prototype declarations.
306  */
307 #ifdef UNWIDENED_PROTOTYPES
308 #define CHAR_P char
309 #define SCHAR_P schar
310 #define UCHAR_P uchar
311 #define XCHAR_P xchar
312 #define SHORT_P short
313 #ifndef SKIP_BOOLEAN
314 #define BOOLEAN_P boolean
315 #endif
316 #define ALIGNTYP_P aligntyp
317 #else
318 #ifdef WIDENED_PROTOTYPES
319 #define CHAR_P int
320 #define SCHAR_P int
321 #define UCHAR_P int
322 #define XCHAR_P int
323 #define SHORT_P int
324 #define BOOLEAN_P int
325 #define ALIGNTYP_P int
326 #else
327 /* Neither widened nor unwidened prototypes.  Argument list expansion
328  * by FDECL/VDECL always empty; all xxx_P vanish so defs aren't needed. */
329 #endif
330 #endif
331
332 /* OBJ_P and MONST_P should _only_ be used for declaring function pointers.
333  */
334 #if defined(ULTRIX_PROTO) && !defined(__STDC__)
335 /* The ultrix 2.0 and 2.1 compilers (on Ultrix 4.0 and 4.2 respectively) can't
336  * handle "struct obj *" constructs in prototypes.  Their bugs are different,
337  * but both seem to work if we put "void*" in the prototype instead.  This
338  * gives us minimal prototype checking but avoids the compiler bugs.
339  */
340 #define OBJ_P void *
341 #define MONST_P void *
342 #else
343 #define OBJ_P struct obj *
344 #define MONST_P struct monst *
345 #endif
346
347 #if 0
348 /* The problem below is still the case through 4.0.5F, but the suggested
349  * compiler flags in the Makefiles suppress the nasty messages, so we don't
350  * need to be quite so drastic.
351  */
352 #if defined(__sgi) && !defined(__GNUC__)
353 /*
354  * As of IRIX 4.0.1, /bin/cc claims to be an ANSI compiler, but it thinks
355  * it's impossible for a prototype to match an old-style definition with
356  * unwidened argument types.  Thus, we have to turn off all NetHack
357  * prototypes, and avoid declaring several system functions, since the system
358  * include files have prototypes and the compiler also complains that
359  * prototyped and unprototyped declarations don't match.
360  */
361 #undef NDECL
362 #undef FDECL
363 #undef VDECL
364 #define NDECL(f) f()
365 #define FDECL(f, p) f()
366 #define VDECL(f, p) f()
367 #undef VOID_ARGS
368 #define VOID_ARGS /*empty*/
369 #endif
370 #endif
371
372 /* MetaWare High-C defaults to unsigned chars */
373 /* AIX 3.2 needs this also */
374 #if defined(__HC__) || defined(_AIX32)
375 #undef signed
376 #endif
377
378 /*
379  * Allow gcc2 to check parameters of printf-like calls with -Wformat;
380  * append this to a prototype declaration (see pline() in extern.h).
381  */
382 #ifdef __GNUC__
383 #if __GNUC__ >= 2
384 #define PRINTF_F(f, v) __attribute__((format(printf, f, v)))
385 #endif
386 #if __GNUC__ >= 3
387 #define UNUSED __attribute__((unused))
388 #define NORETURN __attribute__((noreturn))
389 #endif
390 #endif
391
392 #ifndef PRINTF_F
393 #define PRINTF_F(f, v)
394 #endif
395 #ifndef UNUSED
396 #define UNUSED
397 #endif
398 #ifndef NORETURN
399 #define NORETURN
400 #endif
401
402 #endif /* TRADSTDC_H */