/* LINTLIBRARY */

/*	@(#)c_varieties.h 1.11 91/10/07 SMI	*/

/*
 *	Copyright (c) 1988,1989,1990 by Sun Microsystems
 */
#ifndef _C_VARIETIES_H
#define _C_VARIETIES_H

/**************************************************************************\
 *						 			  *
 *			    >>> WARNING <<<				  *
 *									  *
 *	This file is provided for backward compatibility purpose only.    *
 *	It will be phased out in future releases of Sun C++.  No new	  *
 *	code should be written with the macros below.  Existing code	  *
 *	should be modified to ensure forward compatibility. 	 	  *
 *									  *
 *	The following format, which is similar to that in SunOS 5.0 	  *
 *	system header files, is the recommended way to achieve 		  *
 *	portability among different C dialects in SunOS 5.0.		  *
 *									  *
 *   		#ifndef _FOO_H						  *
 *   		#define _FOO_H						  *
 *									  *
 *  		#ifdef __cplusplus	// for C++ only			  *
 *		extern "C" {						  *
 *  		#endif							  *
 *									  *
 *		#if defined(__STDC__)	// for both Sun C++ and ANSI-C	  *
 *		extern int foo(char*);					  *
 *		#else			// for K&R C			  *
 *		extern int foo();					  *
 *		#endif							  *
 *									  *
 *		#ifdef __cplusplus					  *
 *		}							  *
 *		#endif							  *
 *									  *
 *		#endif							  *
 *									  *
\**************************************************************************/

/*
 *	This file defines some macros that are used to make code
 *	portable among the major C dialects currently in use at
 *	Sun.  As of 12/90, these include Sun C (a lot like K&R C),
 *	ANSI C, and C++.
 *
 * external functions:
 *	To declare an external function, invoke the EXTERN_FUNCTION
 *	macro; the macro's first parameter should be the function's
 *	return type and function name, and the second macro parameter
 *	should be the parenthesized list of function arguments (or an
 *	ellipsis - DOTDOTDOT macro should be used to indicate the 
 *      ellipsis as explained later in this file - if the arguments are 
 *      unspecified or of varying number or type, or the uppercase word 
 *      "_VOID_" if the function takes no arguments).  Some examples:
 *
 *	    EXTERN_FUNCTION( void printf, (char *, DOTDOTDOT) );
 *	    EXTERN_FUNCTION( int fread, (char*, int, int, FILE*) );
 *	    EXTERN_FUNCTION( int getpid, (_VOID_) );
 *
 *	Note that to be ANSI-C conformant, one should put "," at the end
 *	first argument of printf() declaration.
 *
 * Pointers to functions declared as struct members or function arguments:
 *	Ideally, all pointers to function types should be declared with
 *	the exact function argument types for C++ and ANSI-C, as in
 *
 *	    struct xp_ops {
 *	    #if defined(__STDC__)
 *           	bool_t      (*xp_recv)(SVCXPRT *, struct rpc_msg *);
 *			....
 *          #else
 *		bool_t      (*xp_recv)();
 *			....
 *	    };
 *
 *	    EXTERN_FUNCTION(int foo, (char*, int (*func) (int, char)));
 *
 *	In the event when the argument types of the function pointer may
 * 	vary depending on the situation, one can use DOTDOTDOT to tell
 *	C++ not to be so uptight.  Using this method may require pointer
 *	casting when actual assignments or function calls take place,
 *	because ellipses "..." in function pointers does not work as
 *	a wildcard.  It is meant to match only those pointers to functions
 *	that are defined specifically to take variable arguments.
 *	Note that for ANSI-C, at least one argument has to be provided 
 *	before the ellipses.
 *
 *	    struct foo {
 *		    int	(*f)( int, DOTDOTDOT );
 *		    . . .
 *	    };
 *
 */

typedef void (*_PFV_)();
typedef int (*_PFI_)();

/* Which type of C/C++ compiler are we using? */

#if defined(__cplusplus)
    /*
     * Definitions for C++ 2.0 and later require extern "C" { decl; }
     */
#   define EXTERN_FUNCTION( rtn, args ) extern "C" { rtn args; }
#   define DOTDOTDOT ...
#   define _VOID_ void

#elif defined(__STDC__)
    /*
     * Definitions for ANSI C
     */
#   define EXTERN_FUNCTION( rtn, args ) rtn args
#   define DOTDOTDOT ...
#   define _VOID_ void

#else
    /*
     * Definitions for Sun/K&R C -- ignore function prototypes,
     * but preserve tag names and enum bitfield declarations.
     */
#   define EXTERN_FUNCTION( rtn, args ) rtn()
#   define DOTDOTDOT
#   define _VOID_
    /* VOID is only used where it disappears anyway */

#endif /* Which type of C/C++ compiler are we using? */

#endif /* defined(_C_VARIETIES_H) */

