OSDN Git Service

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