Files
nethack/include/tradstdc.h
nethack.allison 7f0f43e6f9 add some unicode support (trunk only)
This patch attempts to add some levels of unicode support
to NetHack.

The master on/off switch for any Unicode support is
defining UNICODE_SUPPORT in config.h. Currently
there is code support for two subsets of unicode support:

UNICODE_DRAWING

If UNICODE_DRAWING is defined, then the data
structures used to house drawing symbols are expanded
to the size of wchar_t, big enough to hold unicode characters.
A typdef called `nhsym' is involved and if UNICODE_DRAWING
is defined, it is wchar_t, otherwise it is uchar.

UNICODE_WIDEWINPORT

If UNICODE_WIDEWINPORT is defined, then the data
structures inside the window port are expanded to the size of
wchar_t, big enough to hold unicode characters.  Both map
symbols and text within the window port are expanded, in order
for potential support for displaying multinational characters some
day, but this patch only provides viewing of map symbols.
A typdef called `nhwchar' is involved and if UNICODE_WIDEWINPORT
is defined, it is wchar_t, otherwise it is char.

The only window port with code support for UNICODE_WIDEWINPORT
currently is the TTY port.  Don't enable UNICODE_WIDEWINPORT
unless:
- it is a TTY port
- the underlying platform specific routines can
handle the larger data structures.

Don't enable UNICODE_SUPPORT unless:
- your compiler can handle wchar_t.
- your compiler can accept L'a' characters.
- your compiler can accept L"wide" strings.

Note that if your compiler can handle the above, you could
enable the larger data structures (currently if TTY) even if your
platform can't actually display unicode or UTF-8, by messing
with u_putch() in win/tty/wintty.c to only deal regular chars.
That should be the only function that actually pushes wide characters
out to the display.

If you enable UNICODE_SUPPORT, and your platform is capable
you will need to turn on the unicode run-time option to be able to
load unicode character sets from the symbol file, to be able to
push unicode characters to the display. You'll also want to load
a unicode symbol set once the unicode option is toggled on. In
a config file you would do that via these two lines:
OPTIONS=unicode
OPTIONS=symset:Unicode_non_US

The repository was stamped with NETHACK_PRE_UNICODE
prior to applying this patch, and stamped with
NETHACK_POST_UNICODE afterwards. The code differences
between those two tagged versions are this patch.
2006-10-17 23:55:42 +00:00

336 lines
10 KiB
C

/* SCCS Id: @(#)tradstdc.h 3.5 2006/07/07 */
/* 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 */
#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)
# 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)
# define WIDENED_PROTOTYPES
# 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
# define NHWCHAR_P nhwchar
#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
# define NHWCHAR_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
#endif
#ifndef PRINTF_F
#define PRINTF_F(f,v)
#endif
#endif /* TRADSTDC_H */