/* NetHack 3.6 tradstdc.h $NHDT-Date: 1501803107 2017/08/03 23:31:47 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.29 $ */ /* 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 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 facilities (only ANSI compilers * should do this, and only if the library supports it). * USE_VARARGS means use the 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 instead of */ /* #define USE_OLDARGS */ /* don't use any variable argument facilities */ #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 #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); \ } #define VA_PASS1(a1) a1 #if defined(ULTRIX_PROTO) && !defined(_VA_LIST_) #define _VA_LIST_ /* prevents multiple def in stdio.h */ #endif #else #ifdef USE_VARARGS #include #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); \ } #define VA_PASS1(a1) a1 #else /*USE_OLDARGS*/ /* * CAVEAT: passing double (including float promoted to double) will * almost certainly break this, as would any integer type bigger than * sizeof (char *). * NetHack avoids floating point, and any configuration able to use * 'long long int' or I64P32 or the like should be using USE_STDARG. */ #ifndef VA_TYPE typedef const char *vA; #define VA_TYPE #endif #define VA_ARGS arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 #define VA_DECL(typ1, var1) \ (var1, VA_ARGS) typ1 var1; vA VA_ARGS; \ { #define VA_DECL2(typ1, var1, typ2, var2) \ (var1, var2, VA_ARGS) typ1 var1; typ2 var2; vA VA_ARGS; \ { #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. [nethack's core doesn't use VA_NEXT() so doesn't use VA_SHIFT() either, and this definition is just retained for completeness. lev_comp does use VA_NEXT(), but it passes all 'argX' arguments.] */ #define VA_SHIFT() \ (arg1 = arg2, arg2 = arg3, arg3 = arg4, arg4 = arg5, arg5 = arg6, \ arg6 = arg7, arg7 = arg8, arg8 = arg9, arg9 = 0) #define VA_NEXT(var1, typ1) ((var1 = (typ1) arg1), VA_SHIFT(), var1) #define VA_END() } /* needed in pline.c, where full number of arguments is known and expected */ #define VA_PASS1(a1) \ (vA) a1, (vA) 0, (vA) 0, (vA) 0, (vA) 0, (vA) 0, (vA) 0, (vA) 0, (vA) 0 #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 <> 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) && !defined(USE_OLDARGS) #define PRINTF_F(f, v) __attribute__((format(printf, f, v))) #endif #if __GNUC__ >= 3 #define UNUSED __attribute__((unused)) #define NORETURN __attribute__((noreturn)) #endif #endif #ifndef PRINTF_F #define PRINTF_F(f, v) #endif #ifndef UNUSED #define UNUSED #endif #ifndef NORETURN #define NORETURN #endif #endif /* TRADSTDC_H */