Make the variadic functions look more like ordinary code rather than
have the function opening brace be hidden inside the VA_DECL() macro.
That brace is still there, but VA_DECL() now needs to be followed by
a visible brace (which introduces a nested block rather than the
start of the funciton). VA_END() now provides a hidden closing brace
to end the nested block, and the existing closing brace still matches
the one in VA_DECL().
Sample usage:
void foo VA_DECL(int, arg) --macro expansion has a hidden opening brace
{ --new, explicit opening brace (actually introduces a nested block)
VA_START(bar);
...code for foo...
VA_END(); --expansion now provides a closing brace for the nested block
} --existing closing brace, still pairs with the hidden one in VA_DECL()
This should help if/when another round of reformatting ever takes place,
and also with editors or other tools that do brace/bracket/parenthesis
matching.
I had forgotten that there were variadic functions in sys/* and ended
up modifying a lot more files than intended. The majority of changes
to those just inserted a new '{' line so that revised VA_END()'s '}'
won't introduce a syntax error. A couple of them needed VA_END() moved
so that local variables wouldn't go out of scope too soon. Only the
Unix ones have been tested.
371 lines
12 KiB
C
371 lines
12 KiB
C
/* NetHack 3.6 tradstdc.h $NHDT-Date: 1431737043 2015/05/16 00:44:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.22 $ */
|
|
/* NetHack 3.6 tradstdc.h $Date: 2012/01/11 18:23:26 $ $Revision: 1.15 $ */
|
|
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
|
/* NetHack may be freely redistributed. See license for details. */
|
|
|
|
#ifndef TRADSTDC_H
|
|
#define TRADSTDC_H
|
|
|
|
#if defined(DUMB) && !defined(NOVOID)
|
|
#define NOVOID
|
|
#endif
|
|
|
|
#ifdef NOVOID
|
|
#define void int
|
|
#endif
|
|
|
|
/*
|
|
* Borland C provides enough ANSI C compatibility in its Borland C++
|
|
* mode to warrant this. But it does not set __STDC__ unless it compiles
|
|
* in its ANSI keywords only mode, which prevents use of <dos.h> and
|
|
* far pointer use.
|
|
*/
|
|
#if (defined(__STDC__) || defined(__TURBOC__)) && !defined(NOTSTDC)
|
|
#define NHSTDC
|
|
#endif
|
|
|
|
#if defined(ultrix) && defined(__STDC__) && !defined(__LANGUAGE_C)
|
|
/* Ultrix seems to be in a constant state of flux. This check attempts to
|
|
* set up ansi compatibility if it wasn't set up correctly by the compiler.
|
|
*/
|
|
# ifdef mips
|
|
# define __mips mips
|
|
# endif
|
|
# ifdef LANGUAGE_C
|
|
# define __LANGUAGE_C LANGUAGE_C
|
|
# endif
|
|
#endif
|
|
|
|
/*
|
|
* ANSI X3J11 detection.
|
|
* Makes substitutes for compatibility with the old C standard.
|
|
*/
|
|
|
|
/* Decide how to handle variable parameter lists:
|
|
* USE_STDARG means use the ANSI <stdarg.h> facilities (only ANSI compilers
|
|
* should do this, and only if the library supports it).
|
|
* USE_VARARGS means use the <varargs.h> facilities. Again, this should only
|
|
* be done if the library supports it. ANSI is *not* required for this.
|
|
* Otherwise, the kludgy old methods are used.
|
|
* The defaults are USE_STDARG for ANSI compilers, and USE_OLDARGS for
|
|
* others.
|
|
*/
|
|
|
|
/* #define USE_VARARGS */ /* use <varargs.h> instead of <stdarg.h> */
|
|
/* #define USE_OLDARGS */ /* don't use any variable argument facilites */
|
|
|
|
#if defined(apollo) /* Apollos have stdarg(3) but not stdarg.h */
|
|
# define USE_VARARGS
|
|
#endif
|
|
|
|
#if defined(NHSTDC) || defined(ULTRIX_PROTO) || defined(MAC)
|
|
# if !defined(USE_VARARGS) && !defined(USE_OLDARGS) && !defined(USE_STDARG)
|
|
# define USE_STDARG
|
|
# endif
|
|
#endif
|
|
|
|
#ifdef NEED_VARARGS /* only define these if necessary */
|
|
/*
|
|
* These have changed since 3.4.3. VA_END() now provides an explicit
|
|
* closing brace to complement VA_DECL()'s hidden opening brace, so code
|
|
* started with VA_DECL() needs an extra opening brace to complement
|
|
* the explicit final closing brace. This was done so that the source
|
|
* would look less strange, where VA_DECL() appeared to introduce a
|
|
* function whose opening brace was missing; there are now visible and
|
|
* invisible braces at beginning and end. Sample usage:
|
|
void foo VA_DECL(int, arg) --macro expansion has a hidden opening brace
|
|
{ --new, explicit opening brace (actually introduces a nested block)
|
|
VA_START(bar);
|
|
...code for foo...
|
|
VA_END(); --expansion now provides a closing brace for the nested block
|
|
} --existing closing brace, still pairs with the hidden one in VA_DECL()
|
|
* Reading the code--or using source browsing tools which match braces--
|
|
* results in seeing a matched set of braces. Usage of VA_END() is
|
|
* potentially trickier, but nethack uses it in a straightforward manner.
|
|
*/
|
|
|
|
#ifdef USE_STDARG
|
|
#include <stdarg.h>
|
|
# define VA_DECL(typ1,var1) (typ1 var1, ...) { va_list the_args;
|
|
# define VA_DECL2(typ1,var1,typ2,var2) \
|
|
(typ1 var1, typ2 var2, ...) { va_list the_args;
|
|
# define VA_INIT(var1,typ1)
|
|
# define VA_NEXT(var1,typ1) var1 = va_arg(the_args, typ1)
|
|
# define VA_ARGS the_args
|
|
# define VA_START(x) va_start(the_args, x)
|
|
# define VA_END() va_end(the_args); }
|
|
# if defined(ULTRIX_PROTO) && !defined(_VA_LIST_)
|
|
# define _VA_LIST_ /* prevents multiple def in stdio.h */
|
|
# endif
|
|
#else
|
|
# ifdef USE_VARARGS
|
|
#include <varargs.h>
|
|
# define VA_DECL(typ1,var1) (va_alist) va_dcl {\
|
|
va_list the_args; typ1 var1;
|
|
# define VA_DECL2(typ1,var1,typ2,var2) (va_alist) va_dcl {\
|
|
va_list the_args; typ1 var1; typ2 var2;
|
|
# define VA_ARGS the_args
|
|
# define VA_START(x) va_start(the_args)
|
|
# define VA_INIT(var1,typ1) var1 = va_arg(the_args, typ1)
|
|
# define VA_NEXT(var1,typ1) var1 = va_arg(the_args,typ1)
|
|
# define VA_END() va_end(the_args); }
|
|
# else
|
|
# define VA_ARGS arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9
|
|
# define VA_DECL(typ1,var1) (var1,VA_ARGS) typ1 var1; \
|
|
char *arg1,*arg2,*arg3,*arg4,*arg5,*arg6,*arg7,*arg8,*arg9; {
|
|
# define VA_DECL2(typ1,var1,typ2,var2) (var1,var2,VA_ARGS) \
|
|
typ1 var1; typ2 var2; \
|
|
char *arg1,*arg2,*arg3,*arg4,*arg5,*arg6,*arg7,*arg8,*arg9; {
|
|
# define VA_START(x)
|
|
# define VA_INIT(var1,typ1)
|
|
/* this is inherently risky, and should only be attempted as a
|
|
very last resort; manipulating arguments which haven't actually
|
|
been passed may or may not cause severe trouble depending on
|
|
the function-calling/argument-passing mechanism being used */
|
|
# define VA_SHIFT() (arg1=arg2, arg2=arg3, arg3=arg4, arg4=arg5,\
|
|
arg5=arg6, arg6=arg7, arg7=arg8, arg8=arg9)
|
|
# define VA_NEXT(var1,typ1) ((var1 = (typ1)arg1), VA_SHIFT(), var1)
|
|
# define VA_END() }
|
|
# endif
|
|
#endif
|
|
|
|
#endif /* NEED_VARARGS */
|
|
|
|
#if defined(NHSTDC) || defined(MSDOS) || defined(MAC) || defined(ULTRIX_PROTO) || defined(__BEOS__)
|
|
|
|
/*
|
|
* Used for robust ANSI parameter forward declarations:
|
|
* int VDECL(sprintf, (char *, const char *, ...));
|
|
*
|
|
* NDECL() is used for functions with zero arguments;
|
|
* FDECL() is used for functions with a fixed number of arguments;
|
|
* VDECL() is used for functions with a variable number of arguments.
|
|
* Separate macros are needed because ANSI will mix old-style declarations
|
|
* with prototypes, except in the case of varargs, and the OVERLAY-specific
|
|
* trampoli.* mechanism conflicts with the ANSI <<f(void)>> syntax.
|
|
*/
|
|
|
|
# define NDECL(f) f(void) /* overridden later if USE_TRAMPOLI set */
|
|
|
|
# define FDECL(f,p) f p
|
|
|
|
# if defined(MSDOS) || defined(USE_STDARG)
|
|
# define VDECL(f,p) f p
|
|
# else
|
|
# define VDECL(f,p) f()
|
|
# endif
|
|
|
|
/*
|
|
* Used for definitions of functions which take no arguments to force
|
|
* an explicit match with the NDECL prototype. Needed in some cases
|
|
* (MS Visual C 2005) for functions called through pointers.
|
|
*/
|
|
#define VOID_ARGS void
|
|
|
|
/* generic pointer, always a macro; genericptr_t is usually a typedef */
|
|
# define genericptr void *
|
|
|
|
# if (defined(ULTRIX_PROTO) && !defined(__GNUC__)) || defined(OS2_CSET2)
|
|
/* Cover for Ultrix on a DECstation with 2.0 compiler, which coredumps on
|
|
* typedef void * genericptr_t;
|
|
* extern void a(void(*)(int, genericptr_t));
|
|
* Using the #define is OK for other compiler versions too.
|
|
*/
|
|
/* And IBM CSet/2. The redeclaration of free hoses the compile. */
|
|
# define genericptr_t genericptr
|
|
# else
|
|
# if !defined(NHSTDC) && !defined(MAC)
|
|
# define const
|
|
# define signed
|
|
# define volatile
|
|
# endif
|
|
# endif
|
|
|
|
/*
|
|
* Suppress `const' if necessary and not handled elsewhere.
|
|
* Don't use `#if defined(xxx) && !defined(const)'
|
|
* because some compilers choke on `defined(const)'.
|
|
* This has been observed with Lattice, MPW, and High C.
|
|
*/
|
|
# if (defined(ULTRIX_PROTO) && !defined(NHSTDC)) || defined(apollo)
|
|
/* the system header files don't use `const' properly */
|
|
# ifndef const
|
|
# define const
|
|
# endif
|
|
# endif
|
|
|
|
#else /* NHSTDC */ /* a "traditional" C compiler */
|
|
|
|
# define NDECL(f) f()
|
|
# define FDECL(f,p) f()
|
|
# define VDECL(f,p) f()
|
|
|
|
#define VOID_ARGS /*empty*/
|
|
|
|
# if defined(AMIGA) || defined(HPUX) || defined(POSIX_TYPES) || defined(__DECC) || defined(__BORLANDC__)
|
|
# define genericptr void *
|
|
# endif
|
|
# ifndef genericptr
|
|
# define genericptr char *
|
|
# endif
|
|
|
|
/*
|
|
* Traditional C compilers don't have "signed", "const", or "volatile".
|
|
*/
|
|
# define signed
|
|
# define const
|
|
# define volatile
|
|
|
|
#endif /* NHSTDC */
|
|
|
|
#ifndef genericptr_t
|
|
typedef genericptr genericptr_t; /* (void *) or (char *) */
|
|
#endif
|
|
|
|
#if defined(MICRO) || defined(WIN32)
|
|
/* We actually want to know which systems have an ANSI run-time library
|
|
* to know which support the %p format for printing pointers.
|
|
* Due to the presence of things like gcc, NHSTDC is not a good test.
|
|
* So we assume microcomputers have all converted to ANSI and bigger
|
|
* computers which may have older libraries give reasonable results with
|
|
* casting pointers to unsigned long int (fmt_ptr() in alloc.c).
|
|
*/
|
|
# define HAS_PTR_FMT
|
|
#endif
|
|
|
|
/*
|
|
* According to ANSI, prototypes for old-style declarations must widen the
|
|
* arguments to int. However, the MSDOS compilers accept shorter arguments
|
|
* (char, short, etc.) in prototypes and do typechecking with them. Therefore
|
|
* this mess to allow the better typechecking while also allowing some
|
|
* prototypes for the ANSI compilers so people quit trying to fix the
|
|
* prototypes to match the standard and thus lose the typechecking.
|
|
*/
|
|
#if defined(MSDOS) && !defined(__GO32__)
|
|
# define UNWIDENED_PROTOTYPES
|
|
#endif
|
|
#if defined(AMIGA) && !defined(AZTEC_50)
|
|
# define UNWIDENED_PROTOTYPES
|
|
#endif
|
|
#if defined(macintosh) && (defined(__SC__) || defined(__MRC__))
|
|
# define WIDENED_PROTOTYPES
|
|
#endif
|
|
#if defined(__MWERKS__) && defined(__BEOS__)
|
|
# define UNWIDENED_PROTOTYPES
|
|
#endif
|
|
#if defined(WIN32)
|
|
# define UNWIDENED_PROTOTYPES
|
|
#endif
|
|
|
|
#if defined(ULTRIX_PROTO) && defined(ULTRIX_CC20)
|
|
# define UNWIDENED_PROTOTYPES
|
|
#endif
|
|
#if defined(apollo)
|
|
# define UNWIDENED_PROTOTYPES
|
|
#endif
|
|
|
|
#ifndef UNWIDENED_PROTOTYPES
|
|
# if defined(NHSTDC) || defined(ULTRIX_PROTO) || defined(THINK_C)
|
|
# ifndef WIDENED_PROTOTYPES
|
|
# define WIDENED_PROTOTYPES
|
|
# endif
|
|
# endif
|
|
#endif
|
|
|
|
/* These are used for arguments within FDECL/VDECL prototype declarations.
|
|
*/
|
|
#ifdef UNWIDENED_PROTOTYPES
|
|
# define CHAR_P char
|
|
# define SCHAR_P schar
|
|
# define UCHAR_P uchar
|
|
# define XCHAR_P xchar
|
|
# define SHORT_P short
|
|
# ifndef SKIP_BOOLEAN
|
|
# define BOOLEAN_P boolean
|
|
# endif
|
|
# define ALIGNTYP_P aligntyp
|
|
#else
|
|
# ifdef WIDENED_PROTOTYPES
|
|
# define CHAR_P int
|
|
# define SCHAR_P int
|
|
# define UCHAR_P int
|
|
# define XCHAR_P int
|
|
# define SHORT_P int
|
|
# define BOOLEAN_P int
|
|
# define ALIGNTYP_P int
|
|
# else
|
|
/* Neither widened nor unwidened prototypes. Argument list expansion
|
|
* by FDECL/VDECL always empty; all xxx_P vanish so defs aren't needed. */
|
|
# endif
|
|
#endif
|
|
|
|
/* OBJ_P and MONST_P should _only_ be used for declaring function pointers.
|
|
*/
|
|
#if defined(ULTRIX_PROTO) && !defined(__STDC__)
|
|
/* The ultrix 2.0 and 2.1 compilers (on Ultrix 4.0 and 4.2 respectively) can't
|
|
* handle "struct obj *" constructs in prototypes. Their bugs are different,
|
|
* but both seem to work if we put "void*" in the prototype instead. This
|
|
* gives us minimal prototype checking but avoids the compiler bugs.
|
|
*/
|
|
# define OBJ_P void*
|
|
# define MONST_P void*
|
|
#else
|
|
# define OBJ_P struct obj *
|
|
# define MONST_P struct monst *
|
|
#endif
|
|
|
|
#if 0
|
|
/* The problem below is still the case through 4.0.5F, but the suggested
|
|
* compiler flags in the Makefiles suppress the nasty messages, so we don't
|
|
* need to be quite so drastic.
|
|
*/
|
|
#if defined(__sgi) && !defined(__GNUC__)
|
|
/*
|
|
* As of IRIX 4.0.1, /bin/cc claims to be an ANSI compiler, but it thinks
|
|
* it's impossible for a prototype to match an old-style definition with
|
|
* unwidened argument types. Thus, we have to turn off all NetHack
|
|
* prototypes, and avoid declaring several system functions, since the system
|
|
* include files have prototypes and the compiler also complains that
|
|
* prototyped and unprototyped declarations don't match.
|
|
*/
|
|
# undef NDECL
|
|
# undef FDECL
|
|
# undef VDECL
|
|
# define NDECL(f) f()
|
|
# define FDECL(f,p) f()
|
|
# define VDECL(f,p) f()
|
|
# undef VOID_ARGS
|
|
# define VOID_ARGS /*empty*/
|
|
#endif
|
|
#endif
|
|
|
|
|
|
/* MetaWare High-C defaults to unsigned chars */
|
|
/* AIX 3.2 needs this also */
|
|
#if defined(__HC__) || defined(_AIX32)
|
|
# undef signed
|
|
#endif
|
|
|
|
|
|
/*
|
|
* Allow gcc2 to check parameters of printf-like calls with -Wformat;
|
|
* append this to a prototype declaration (see pline() in extern.h).
|
|
*/
|
|
#ifdef __GNUC__
|
|
# if __GNUC__ >= 2
|
|
# define PRINTF_F(f,v) __attribute__ ((format (printf, f, v)))
|
|
# endif
|
|
# if __GNUC__ >= 3
|
|
# define UNUSED __attribute__ ((unused))
|
|
# endif
|
|
#endif
|
|
|
|
#ifndef PRINTF_F
|
|
# define PRINTF_F(f,v)
|
|
#endif
|
|
#ifndef UNUSED
|
|
# define UNUSED
|
|
#endif
|
|
|
|
#endif /* TRADSTDC_H */
|