ftp.nice.ch/pub/next/unix/mail/zend.1.0.s.tar.gz#/zend-1.0/include/portansi.h

This is portansi.h in view mode; [Download] [Up]

/*+++*
 *  RCS		$Id: portansi.h,v 1.13 1993/02/02 21:00:42 gerben Exp $
 *  title:	portansi.h
 *  abstract:	`portable ANSI C' conventions.
 *  author:	T.R.Hageman, Groningen, The Netherlands
 *  created:	August 1992
 *  modified:	(see RCS Log at end)
 *  copyleft:
 *
 *		Copyright (C) 1992  Tom R. Hageman.
 *
 *	This is free software; you can redistribute it and/or modify
 *	it under the terms of the GNU General Public License as published by
 *	the Free Software Foundation; either version 2 of the License, or
 *	(at your option) any later version.
 *
 *	This software is distributed in the hope that it will be useful,
 *	but WITHOUT ANY WARRANTY; without even the implied warranty of
 *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *	GNU General Public License for more details.
 *
 *	You should have received a copy of the GNU General Public License
 *	along with this software; if not, write to the Free Software
 *	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 *  description:
 *
 *	This describes `portable ANSI C', a programming convention
 *	to improve portability of C code to compilers with a different
 *	degree of ANSI C compliance.
 *
 *	Command-line defineable options (for verbose explanations see below):
 *
 *	_ANSI_C_		- Compiler's ANSI compliance, in terms of:
 *	    _ANSI_FULL_PROTO_	    - Full ANSI prototype support:
 *		_ANSI_PROTO_		- prototypes allowed,
 *		_ANSI_NAMED_PROTO_	- named arguments in prototypes allowed,
 *		_ANSI_ELLIPSES_		- `...' syntax allowed,
 *	    _ANSI_KEYWORDS_	    - Full ANSI keyword support:
 *		_ANSI_const_		- `const' allowed,
 *		_ANSI_signed_		- `signed' allowed,
 *		_ANSI_Void_		- both `void' and `void *' allowed,
 *		_ANSI_volatile_		- `volatile' allowed,
 *	    _ANSI_DEFUN_	    - ANSI-style function definitions allowed,
 *	    _ANSI_CPP_		    - ANSI-compliant tokenizing preprocessor,
 *	    _ANSI_UNION_	    - unions can be initialized at compile-time,
 *	    _ANSI_ARRAY_	    - can take address of an array,
 *	    _ANSI_COMPLIANT_	    - (all of the above);
 *	    _ANSI_ONLY_VOID_	    - `void' allowed, but not `void *'
 *	_ANSI_CXX_ELLIPSES_	- C++ style ... syntax if not _ANSI_ELLIPSES_
 *	_ANSI_EXACT_PROTO_	- interaction of prototypes with old-style defs;
 *	_ANSI_HEADERS_		- presence of all ANSI headers;
 *	_ANSI_LIBRARY_		- run-time library is ANSI compliant;
 *	_ANSI_VOLATILE_AUTO_	- `volatile' works with `auto' variables;
 *	_STDARG_		- <stdarg.h> vs. <varargs.h>.
 *	_ANSI_TRUE_VOID_	- don't hide `void' if compiler supports it.
 *				  (this means you cannot use `void *';
 *				   use `void_*' -note the underscore- instead)
 *
 *	Some general notes on preprocessor portability:
 *
 *	1) the `#' should be the first character on the line, since most
 *	   oldstyle preprocessors expect it there.  Spaces and tabs are allowed
 *	   between the `#' and the preprocessor directive. (some very obsolete
 *	   preprocessors are rumoured not to allow even this, but you have to
 *	   draw the line somewhere -- I took the 7th Edition pdp-11 compiler
 *	   as the bottomline, and how much lower can you get :-)
 *
 *	2) if you use the `#error' and `#pragma' directives, add whitespace
 *	   before the `#' so oldstyle preprocessors won't choke.
 *	   (if your preprocessor _does_ allow whitespace before `#' but
 *	    does not grok these keywords, you're out of luck...)
 *
 *	3) avoid the `#elif' directive, sorry as it may be.
 *	   (unless inside ANSI C conditional code, and preceded with
 *	    whitespace as described above)
 *
 *	4) all UNIX preprocessors seem to allow the `defined()' operator
 *	   in #if expressions.  On the other hand, I know of at least one
 *	   compiler for the Macintosh that didn't support it in a version
 *	   that was around in 1989.  So this is left to your own judgment.
 *
 *	5) some ancient preprocessors limit the number of significant
 *	   characters in macro names to 8.  You may find this too restrictive;
 *	   most modern preprocessors have relieved this limit to at least 31
 *	   significant characters.  So this is left to your own judgment.
 *
 *	6) some old preprocessors do NOT expand macros that take arguments
 *	   in an `#if' condition. (this smells like a bug.)
 *
 *	7) preprocessors should treat an undefined macro in `#if' expressions
 *	   as if it were defined with a value of `0'.  (I have never heard
 *	   of one that handles undefined macros otherwise...)
 *
 *	(This file is supposed to be portable within all these limitations.)
 *
 *---*/

#ifndef _PORTANSI_H_
#define _PORTANSI_H_	0x110

#if 0			/* {{we cannot use this, see point 6) above.}} */
#ifndef _defined_empty_		/* (see "portdefs.h" for explanation.) */
#   define _defined_empty_(macroname)	(2*macroname-1==2*-1)
#endif
#endif

/*++*
 * _ANSI_C_	Determine ANSI-ness of the compiler.
 *
 * Here we predefine it for some known compilers; for others we derive it
 * from the predefined __STDC__ macro.
 * This can be overridden by a command line definition.
 *--*/

#ifndef _ANSI_C_		/* NOT overridden from command line. */

#   ifdef MSDOS			/* MicroSof C (MSDOS 5.1up) */
#	if 1			/* (can we test the compiler's version?) */
#	    define _ANSI_C_	_ANSI_COMPLIANT_
#	endif
	/* ...except does not define __STDC__ correctly. */
#	define _ANSI_EXACT_PROTO_	1	/* {{really??}} */
#   endif

#   if __TURBOC__		/* Turbo/Borland C (MSDOS 2.0up, Atari ST/TT) */
#	if !(__MSDOS__ && (__TURBOC__ >> 8) < 2)
#	    define _ANSI_C_	_ANSI_COMPLIANT_
#	endif
	/* ...except does not define __STDC__ unless the -A option is given;
	   however this breaks some headers.  For Atari ST Turbo C
	   in particular, with its register-based parameter passing,
	   the use of correct prototypes is mandatory! */
#	define _ANSI_EXACT_PROTO_	1
#	if (__TOS__ && (__TURBOC__ >> 8) <= 2)
#	    define _ANSI_VOLATILE_AUTO_	0
	    /* ...broken `volatile' that does not work with `auto' variables. */
#	endif
#   endif

#   if VAXC			/* VAX C (VMS 3.0up) */
#	if 1			/* (can/need we test the compiler's version?) */
#	    define _ANSI_C_	_ANSI_COMPLIANT_
#	endif
	/* ...except does not define __STDC__ to say it is.  Sigh. */
#   endif

#   if __stdc__			/* seems to be the latest fashion (convex). */
#	define _ANSI_C_		_ANSI_COMPLIANT_
#   endif
#endif


#ifndef _ANSI_C_		/* NOT overridden from command line. */
#   ifdef __STDC__
#	if (__STDC__ - 0 > 0)	/* Strictly conforming ANSI Compiler. */
#	    define _ANSI_C_	_ANSI_COMPLIANT_
#	else			/* __STDC__ <= 0 || __STDC__ == empty */
#	    define _ANSI_C_	_ANSI_COMPLIANT_ - _ANSI_NAMED_PROTO_
#	endif
#   else			/* Add known non-ANSI compilers here. */
#	if (sun && sparc	/* {assume SunOS 4} */	|| \
	    ultrix || __ultrix__ /* {Ultrix 4.3} */	|| \
	    /* Add other systems that know `void *' here */0)
#	    define _ANSI_C_	_ANSI_Void_
#	endif
#   endif
#else				/* overridden from command line. */
#   if ((2*_ANSI_C_-1==2*-1) || _ANSI_C_-0 == 1)
	/* Empty, or 1.  Assume full ANSI C compliance is meant. */
#	undef _ANSI_C_
#	define _ANSI_C_		_ANSI_COMPLIANT_
#   endif
#endif


#ifdef _ANSI_C_

/*++*
 * The following flags describe various aspects of ANSI C compiler support.
 * These can be combined in _ANSI_C_ by OR-ing or adding them together.
 *
 *				0x1     reserved for command-line definition. */
#define _ANSI_PROTO_		0x2  /* Support prototypes? */
#define _ANSI_NAMED_PROTO_	0x4  /* Support argument names in prototypes? */
#define _ANSI_ELLIPSES_		0x8  /* Support `...' in varargs functions? */
#define _ANSI_FULL_PROTO_	0xE  /* Full ANSI prototypes supported? */
#define _ANSI_const_		0x10 /* knows `const' keyword? */
#define _ANSI_signed_		0x20 /* knows `signed' keyword? */
#define _ANSI_Void_		0x40 /* knows both `void' and `void *'? */
#define _ANSI_volatile_		0x80 /* knows `volatile' keyword? */
#define _ANSI_KEYWORDS_		0xF0 /* knows all ANSI keywords. */
#define _ANSI_DEFUN_		0x100/* ANSI-style function definitions? */
#define _ANSI_CPP_		0x200/* ANSI-style tokenizing preprocessor? */
#define _ANSI_UNION_		0x400/* unions can be initialized? */
#define _ANSI_ARRAY_		0x800/* can take address of array? */
#define _ANSI_ONLY_VOID_	0x8000/* knows `void' but not `void *'? */
/*--*/
/*
 * {{The next one *must* be unconditionally defined (and its value must be
 *   equal to the logical OR of the above options) so the conditional
 *   #if (_ANSI_C_ == _ANSI_COMPLIANT_) evaluates to the expected value
 *   even if _ANSI_C_ is (partially) undefined.}}
 */
#endif /* _ANSI_C_ */
/*++*/
#define _ANSI_COMPLIANT_	0xFFE/* Full ANSI-compliant compiler. */
/*--*/
#ifdef _ANSI_C_

/*++*
 * Now that we determined the value of _ANSI_C_, UNdefine any flags that
 * are NOT set in it.  This is done so that you can test the existence
 * or non-zeroness of an individual option by its name, as a shorthand
 * to testing its presence in _ANSI_C_.  For instance:
 *
 *	#if _ANSI_CPP_
 *
 * or even
 *
 *	#ifdef _ANSI_CPP_
 *
 * is equivalent to:
 *
 *	#if ((_ANSI_C_) & _ANSI_CPP_)
 *
 * (Note that _ANSI_COMPLIANT_ cannot be treated in this way, since this
 *  would cause the (_ANSI_C_ == _ANSI_COMPLIANT_) and the individual
 *  ((_ANSI_C_) & _ANSI_<option>_) tests to fail for non-compliant compilers.)
 *
 * It is a good idea to enclose _ANSI_C_ in parentheses, since this macro
 * may be defined as a combination of options |-ed together.
 *--*/

#if (_ANSI_C_ != _ANSI_COMPLIANT_)	/* speed up for compliant compilers. */

#if (((_ANSI_C_) & _ANSI_FULL_PROTO_) != _ANSI_FULL_PROTO_)	/* !! */
#   undef _ANSI_FULL_PROTO_
# if !((_ANSI_C_) & _ANSI_PROTO_)
#   undef _ANSI_PROTO_
# endif
# if !((_ANSI_C_) & _ANSI_NAMED_PROTO_)
#   undef _ANSI_NAMED_PROTO_
# endif
# if !((_ANSI_C_) & _ANSI_ELLIPSES_)
#   undef _ANSI_ELLIPSES_
# endif
#endif
#if (((_ANSI_C_) & _ANSI_KEYWORDS_) != _ANSI_KEYWORDS_)		/* !! */
#   undef _ANSI_KEYWORDS_
# if !((_ANSI_C_) & _ANSI_const_)
#   undef _ANSI_const_
# endif
# if !((_ANSI_C_) & _ANSI_signed_)
#   undef _ANSI_signed_
# endif
# if !((_ANSI_C_) & _ANSI_Void_)
#   undef _ANSI_Void_
# endif
# if !((_ANSI_C_) & _ANSI_volatile_)
#   undef _ANSI_volatile_
# endif
#endif
#if !((_ANSI_C_) & _ANSI_DEFUN_)
#   undef _ANSI_DEFUN_
#endif
#if !((_ANSI_C_) & _ANSI_CPP_)
#   undef _ANSI_CPP_
#endif
#if !((_ANSI_C_) & _ANSI_UNION_)
#   undef _ANSI_UNION_
#endif
#if !((_ANSI_C_) & _ANSI_ARRAY_)
#   undef _ANSI_ARRAY_
#endif
#endif /* (_ANSI_C_ != _ANSI_COMPLIANT_) */

#if !((_ANSI_C_) & _ANSI_ONLY_VOID_)				/* !! */
#   undef _ANSI_ONLY_VOID_
#else
#   undef _ANSI_Void_
#   undef _ANSI_KEYWORDS_
#endif

#ifndef _ANSI_VOLATILE_AUTO_
#   if _ANSI_volatile_		/* assume `volatile' works if present */
#	define _ANSI_VOLATILE_AUTO_	1
#   endif
#endif

#endif /* _ANSI_C_ */


/*++*
 * Define dummy keywords if compiler does not have them.
 *
 * Notes:
 *   o	`void' is defined as `char' instead of `int' so we can say `void *'
 *	with the expected result -- in traditional C `char *' serves as
 *	generic pointer.  Also we still get a redeclaration error when an
 *	implicitly declared function is redeclared or -defined `void'.
 *	This does not fully accommodate compilers that do know about `void'
 *	but not about `void *'.  In particular, this screws up parameterless
 *	function prototypes, so you shouldn't use _ANSI_PROTO_ unless
 *	_ANSI_Void_ is also valid.  {{this is debatable; alternatively we
 *	should require the use of a special type instead of `void *', but
 *	that is what I wanted to avoid in the first place (for portability
 *	reasons mainly--I want to be able to plug this into existing code as
 *	painless as possible...)  Anyway, compilers
 *	that support prototypes and `void' but not `void *' seem pretty scarce
 *	so I don't mind--although surely you're free to disagree if you're
 *	stuck up with a beast like that.}}
 *
 *	Well, I devised an alternative: `void' is left alone if the compiler
 *	supports `void' only as indicated by (_ANSI_C_ & _ANSI_ONLY_VOID_),
 *	AND it is explicitly requested by definition of _ANSI_TRUE_VOID_.
 *	The rationale for this explicit request is to make the programmer
 *	aware that (s)he should have to convert `void *'s to `void_*'s.
 *
 *   o	`void_' -note the trailing underscore- is always defined as the
 *	base type of the most generic pointer supported by the compiler, so
 *	you can say ``void_* pointer''.
 *
 *   o	`signed' is defined empty, so it works when used as a type qualifier,
 *	i.e., like `const', but not in casts by itself, like `(signed) aap'.
 *
 *   o	The once-reserved-but-never-alive keyword `entry' is hidden, so you
 *	can use it as a normal identifier.
 *--*/
#if (!_ANSI_KEYWORDS_)
#   if (!_ANSI_const_)
#	define const
#   endif
#   if (!_ANSI_Void_)
#	if (!_ANSI_ONLY_VOID_ || 2*_ANSI_TRUE_VOID_-1==2*0-1)
#	    define void	char
#	    undef _ANSI_PROTO_
#	endif
#	define void_	char
#   endif
#   if (!_ANSI_signed_)
#	define signed
#   endif
#   if (!_ANSI_volatile_)
#	define volatile
#   endif
#   define entry	eNtrY_/* unlikely enough for ya? */
#endif /* _ANSI_KEYWORDS_ */

#ifndef void_
#   define void_	void
#endif

/*++*
 * _ANSI_LIBRARY_	Determine ANSI-ness of run-time library.
 *
 *	If this symbol is non-zero, you may assume that all ANSI C runtime
 *	functions are available, AND are prototyped properly in the
 *	appropriate header.
 *
 *	Here we assume the library is ANSI-compliant if the compiler is.
 *	This can be overridden by a command line definition.
 *--*/

#ifndef _ANSI_LIBRARY_
#   if (_ANSI_C_ == _ANSI_COMPLIANT_)
#	define _ANSI_LIBRARY_	1
#   endif
#else
#   if (2*_ANSI_LIBRARY_-1==2*-1)	/* Empty definition: assume TRUE. */
#	undef _ANSI_LIBRARY_
#	define _ANSI_LIBRARY_	1
#   endif
#endif


/*++*
 * _ANSI_HEADERS_	Determine presence of ANSI headers.
 *
 *	If this symbol is non-zero, you may assume that all headers
 *	ordained by the ANSI C standard are present:
 *
 *	    <assert.h>	<ctype.h>   <errno.h>	<float.h>   <limits.h>
 *	    <locale.h>	<math.h>    <setjmp.h>	<signal.h>  <stdarg.h>
 *	    <stddef.h>	<stdio.h>   <stdlib.h>	<string.h>  <time.h>
 *
 *	Here we assume the headers are ANSI-compliant if the library is.
 *	This can be overridden by a command line definition.
 *--*/

#ifndef _ANSI_HEADERS_
#   if _ANSI_LIBRARY_
#	define _ANSI_HEADERS_	1
#   endif
#else
#   if (2*_ANSI_HEADERS_-1==2*-1)	/* Empty definition: assume TRUE. */
#	undef _ANSI_HEADERS_
#	define _ANSI_HEADERS_	1
#   endif
#endif

/*++*
 * _STDARG_		Determine <stdarg.h> vs. <varargs.h>
 *
 *	Some non-ANSI C systems already use <stdarg.h>, but their library
 *	is not otherwise ANSI-compliant (Minix 1.5 springs to mind...).
 *
 *	Here we assume <stdarg.h> if the library is ANSI-compliant.
 *	This can be overridden by a command line definition.
 *--*/

#ifndef _STDARG_
#   if _ANSI_HEADERS_
#	define _STDARG_	1
#   endif
#else
#   if (2*_STDARG_-1==2*-1)		/* Empty definition: assume TRUE. */
#	undef _STDARG_
#	define _STDARG_	1
#   endif
#endif


/*++*
 * __(arglist)		Prototyping macro.
 * _(argname)		argument name macro for use in ANSI prototypes.
 *
 *	Facilitate function prototyping.  Expands to the most verbose
 *	prototype still supported by the compiler.  The _(argname) macro
 *	is defined only if ANSI prototypes are allowed: if named arguments
 *	are allowed in prototypes (some near-ANSI compilers do not support
 *	these) and we have token catenation, it expands to an unlikely name,
 *	else it ``expands'' to <empty>.
 *
 *	For example:
 *		int	foo __(( void ));
 *		char *	bar __(( int _(bie) ));
 *--*/

#if _ANSI_PROTO_
#   if (_ANSI_NAMED_PROTO_ && _ANSI_CPP_)
#	define _(argname)	_##argname##_
#   else
#	define _(argname)
#   endif
#   define __(arglist)	arglist
#else
#   define __(arglist)	()
#endif


/*++*
 * _ANSI_EXACT_PROTO_	Interaction of ANSI prototypes and old-style
 * _PI_	_PU_		declarations, cf. default argument type promotion.
 *
 * This subject is left unspecified by the ANSI standard.  Inevitably
 * this gave rise to two incompatible interpretations:
 *
 *  1)	(NOT _ANSI_EXACT_PROTO_)
 *	Promoted types should be used in prototypes, for example, if a
 *	funtion is defined as:
 *
 *		int foo(c) char c; { ... }
 *
 *	the corresponding prototype should be:
 *
 *		int foo( int c );
 *
 *	(this seems to be the more common interpretation);
 *
 *  2)	(_ANSI_EXACT_PROTO_)
 *	The presence of a prototype of a function before the oldstyle
 *	definition of that function determines whether or not default
 *	promotion occurs.  That means that (in the presence of prototypes,
 *	at least) no default promotion occurs, i.e., it is equivalent to
 *	an ANSI-style definition.
 *
 *	(IMHO this is the preferred behaviour, since the presence of
 *	 ANSI-style prototypes indicates that the programmer is aware
 *	 of ANSI C and --presumably-- wants ANSI behaviour, without
 *	 sacrificing portability to non-ANSI compilers)
 *
 * Some compilers only generate a warning if function prototype and definition
 * are inconsistent in this respect, others (Gnu C!) mercilessly consider this
 * an error.
 *
 * The _PI_ and _PU_ macros try to deal with this difference, according
 * to the value of _ANSI_EXACT_PROTO_.  In the above example, the
 * prototype would be written as:
 *
 * int foo __(( _PI_(char) _(c) ));
 *
 * A special problem is presented by `unsigned short', since it promotes
 * to `unsigned' if (sizeof(int) == sizeof(short)), and to `int' if
 * (sizeof(int) > sizeof(short)).  This is unfortunate, but we have to
 * live with it, hence the _PU_ macro for the special case of unsigned
 * short types. (which is defined according to the existence of the
 * __MSHORT__ macro --borrowed from gcc-- to expand to the right thing.)
 *
 * (If you don't like this style, you should use the exact argument types
 *  in prototypes, and write function definitions with a manifest
 *  preprocessor conditional, like:
 *
 *	int
 *	#if _ANSI_DEFUN_
 *	foo(char c)
 *	#else
 *	foo(c)	char c;
 *	#endif
 *	{ ...etc. }
 * )
 *--*/

#if _ANSI_PROTO_

#   ifdef _ANSI_EXACT_PROTO_
#	if (2*_ANSI_EXACT_PROTO_-1==2*-1) /* Empty definition: assume TRUE. */
#	    undef _ANSI_EXACT_PROTO_
#	    define _ANSI_EXACT_PROTO_	1
#	endif
#   endif

#   if _ANSI_EXACT_PROTO_
#	define _PI_(type)	type
#	define _PU_(type)	type
#   else
#	define _PI_(type)	int
#	ifdef __MSHORT__
#	    define _PU_(type)	unsigned
#	else
#	    define _PU_(type)	int
#	endif
#   endif
#endif


/*++*
 * DEFVARG, va_begin, ___	<stdarg.h> vs. <varargs.h>
 *
 * Some compilers _require_ ANSI-style definitions, as well as ANSI-style
 * prototypes, for functions with variable number of arguments.  Hence the
 * existence of DEFVARG.  It takes as arguments the function's name,
 * its ANSI-style argument list, and its oldstyle argument list including
 * a trailing `va_alist' in the parameter list but without the corresponding
 * `va_dcl' in the parameter declarations--that is added implicitly if
 * necessary.
 *
 * The macro `va_begin' is defined to replace the `va_start' macro, that is
 * defined with a single parameter in <varargs.h> and with two parameters
 * in <varargs.h>.
 *
 * The macro `___' (three underscores) is intended for use in prototypes
 * and ANSI-style definitions of varargs functions.  You should use this
 * instead of `, ...' in prototypes for maximum portability.
 * (some early near-ANSI compilers do not yet support the `ellipses' syntax
 *  and expect just a trailing comma instead; and some even may support the
 *  (early?) C++ syntax (`...' _without_ a comma) -- this is described by
 *  the value of _ANSI_CXX_ELLIPSES_.  However these do not seem
 *  too abundant, so you may decide not to care about this.)
 *
 * For example, consider a function with the following ANSI prototype:
 *
 *	int printf(const char *format, ...);
 *
 * In our `portable ANSI C' would be defined as:
 *
 *	#include "portansi.h"
 *
 *	#if _STDARG_
 *	#   include <stdarg.h>
 *	#else
 *	#   include <varargs.h>
 *	#endif
 *
 *	int printf __(( const char *_(format) ___ ));	// prototype
 *
 *	int
 *	DEFVARG( printf, (const char *format ___),	// definition
 *			 (format, va_alist) const char *format; )
 *	{
 *		va_list ap;
 *
 *		va_begin(ap, format);
 *		etc...
 *	}
 *
 * Note that the programmer should include the correct header, according
 * to the value of _STDARG_.  Also note that for maximum portability the
 * last fixed parameter of a stdarg function should not be declared `register'
 * since many implementations of va_start() do somehow take its address.
 *
 * (If you don't like this style, you can of course still use a manifest
 *  preprocessor conditional, for example:
 *
 *	int
 *	#if (_STDARG_ && _ANSI_DEFUN_)
 *	printf(const char *format ___)
 *	#else
 *	printf(format, va_alist)
 *	const char *format;
 *	va_dcl
 *	#endif
 *	{ etc... }
 *
 *  whatever ticks you off:-)
 *--*/

#if _STDARG_
#   define	va_begin(ap, last)	va_start(ap, last)
#   if _ANSI_DEFUN_
#	define	DEFVARG(fun, proto, traditional)	fun proto
#   else
#	define	DEFVARG(fun, proto, traditional)	fun traditional
#	define	va_dcl
#   endif
#else
#   define	va_begin(ap, last)	va_start(ap)
#   define	DEFVARG(fun, proto, traditional)	fun traditional va_dcl
#endif

#if _ANSI_PROTO_
#   ifndef ___
#	if _ANSI_ELLIPSES_
#	    define ___	, ...
#	else
#	    if _ANSI_CXX_ELLIPSES_
#		define ___
#	    else
#		define ___	,
#	    endif
#	endif
#   endif
#endif


/*++*
 * _ANSI_CAT_(t1, t2)	Token catenation.
 * _ANSI_STR_(t)	Token stringize.
 *
 *	The non-ANSI versions of these macros depend on undocumented behaviour
 *	of traditional ``John F.Reiser''-compatible preprocessors: comments are
 *	completely stripped from the macro expansion; macro arguments are
 *	expanded everywhere, even within strings.
 *
 *	Note that, if you use these in another macro definition and you pass
 *	that macro's arguments to these macros, that argument will be
 *	macro-expanded in ANSI C--which may or may not be what you want.
 *	Also note that traditional preprocessor do not treat double quotes
 *	specially when expanded in a string--it will result in a syntax error.
 *
 *	Finally note that some compilers that claim to be ANSI-compliant
 *	(Turbo ST for the Atari ST, to name one) handle string- and
 *	tokenization just plain _wrong_ by macro-expanding
 *	the arguments _before_ applying string/tokenization!
 *--*/

#if _ANSI_CPP_
#   define _ANSI_CAT_(a1,a2)	a1##a2
#   define _ANSI_STR_(a)	#a
#else
#   define _ANSI_CAT_(t1,t2)	t1/**/t2
#   define _ANSI_STR_(t)	"t"
#endif

#endif /* _PORTANSI_H_ */

/*======================================================================*
 * $Log: portansi.h,v $
 * Revision 1.13  1993/02/02  21:00:42  gerben
 * *** empty log message ***
 *
 * Revision 1.12  1993/01/26  18:43:06  tom
 * some textual cleanup.
 *
 * Revision 1.11  1992/12/30  12:21:24  tom
 * buildin SunOS 4.1 and Ultrix 4.3 native compilers (both know void *).
 *
 * Revision 1.10  1992/12/22  14:35:50  tom
 * some comment changes.
 *
 * Revision 1.9  1992/12/18  22:57:45  tom
 * *** empty log message ***
 *
 * Revision 1.8  1992/10/23  04:53:28  tom
 * move handling of _ANSI_ONLY_VOID_ outside _ANSI_C_!=_ANSI_COMPLIANT_.
 *
 * Revision 1.7  1992/10/23  02:52:13  tom
 * add _ANSI_ONLY_VOID_ compiler flag; _ANSI_TRUE_VOID_ option; generic
 * pointer base type `void_'; fix bug in handling non-compliant flags--
 * test _ANSI_FULL_PROTO_ and _ANSI_KEYWORDS_ masks BEFORE individual members
 * are turned off.
 *
 * Revision 1.6  1992/10/21  19:40:23  tom
 * some comment changes.
 *
 * Revision 1.5  1992/10/10  00:51:49  tom
 * add _ANSI_UNION_, _ANSI_ARRAY_ flags; rename _ANSI_void_ to _ANSI_Void_
 * to emphasize that both `void' and `void *' should be recognized by the
 * compiler (and to uniquize it within 8 characters); bypass builtin
 * compilers if _ANSI_C_ is already defined; document _ANSI_CXX_ELLIPSES_;
 * describe dummy keywords and move it to the front; add some comments.
 *
 * Revision 1.4  1992/10/03  01:01:26  tom
 * add copyleft; clarify description and comments; parenthize _ANSI_C_;
 * support C++ like varargs syntax by changing definition of `___' macro.
 *
 * Revision 1.3  1992/09/16  21:30:02  tom
 * more detailed _ANSI_C_ parametrization; add _ANSI_VOLATILE_AUTO_;
 * add `___' macro for `...' syntax; remove __exiting (moved to "portab.h").
 *
 * Revision 1.2  1992/09/14  04:43:40  tom
 * some documentation fixes; add _ANSI_HEADERS_; fix default definition
 * of _ANSI_EXACT_PROTO_.
 *
 * Revision 1.1  1992/09/11  14:36:37  tom
 * Add some comments; add option undefs for shorthand tests.
 *
 * Revision 1.0  1992/09/10  07:57:01  tom
 * Initial revision
 *
 *======================================================================*/

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.