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.