/* @(#)xv_c_types.h 1.9 93/06/28 SMI */ /* * (c) Copyright 1989 Sun Microsystems, Inc. Sun design patents * pending in the U.S. and foreign countries. See LEGAL NOTICE * file for terms of the license. */ #ifndef XV_C_TYPES_H #define XV_C_TYPES_H #ifndef C_VARIETIES_H #define C_VARIETIES_H /* * This file defines some macros that are used to make code * portable between the major C dialects currently in use at * Sun. As of 12/88, 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_) ); * EXTERN_FUNCTION( int atoi, (CONST char *str) ); * * Note that to be ANSI-C conformant, one should put "," at the end * first argument of printf() declaration. * * structure tags: * In order to handle cases where a structure tag has the same name * as a type, the STRUCT_TAG macro makes the tag disappear in C++. * An example (from ): * * typedef struct STRUCT_TAG(fd_set) { ... } fd_set; * * enum bitfields: * In K&R C as interpreted at UCB, bitfields may be declared to * be of an enumerated type. Neither ANSI C nor C++ permit this, * so the ENUM_BITFIELD macro replaces the enum declaration with * "unsigned". An example (from ): * * struct { * ENUM_BITFIELD( Attr_pkg ) pkg : 8; * unsigned ordinal : 8; * ENUM_BITFIELD( Attr_list_type ) list_type : 8; * ... * }; * * enum type specifier: * In K&R C, it is OK to use "enum xyz" as return type but in C++, * one should use "xyz". ENUM_TYPE macro is used to handle this. * * ENUM_TYPE(enum, xyz) (*func) (...); * * "struct s s;": * C++ does not allow this sort of name conflict, since struct tags are * in the same namespace as variables. In this case, we use the * NAME_CONFLICT macro to prepend (for C++) an underscore to the * variable (or struct member) name. E.g. from : * * typedef struct pixrect { * struct pixrectops *pr_ops; * struct pr_size NAME_CONFLICT(pr_size); * } Pixrect; * #define pr_height NAME_CONFLICT(pr_size).y * #define pr_width NAME_CONFLICT(pr_size).x * * Note that no spaces are allowed within the parentheses in the * invocation of NAME_CONFLICT. * * Pointers to functions declared as struct members: * Instead of getting picky about the types expected by struct * members which are pointers to functions, we use DOTDOTDOT to * tell C++ not to be so uptight: * * struct pixrectops { * int (*pro_rop)( DOTDOTDOT ); * int (*pro_stencil)( DOTDOTDOT ); * int (*pro_batchrop)( DOTDOTDOT ); * . . . * }; * */ /* 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 STRUCT_TAG( tag_name ) /* the tag disappears */ # define ENUM_BITFIELD( enum_type ) unsigned # define ENUM_TYPE( enum_sp, enum_ty ) enum_ty #if defined(__STDC__) || defined(__cplusplus) || defined(c_plusplus) # define NAME_CONFLICT( name ) _##name #else # define NAME_CONFLICT( name ) _/**/name #endif # define DOTDOTDOT ... # define _VOID_ /* anachronism */ # define CONST const /* * This is not necessary for 2.0 since 2.0 has corrected the void (*) () problem */ typedef void (*_PFV_)(); typedef int (*_PFI_)(); #elif defined(c_plusplus) /* * Definitions for C++ 1.2 */ # define EXTERN_FUNCTION( rtn, args ) rtn args # define STRUCT_TAG( tag_name ) /* the tag disappears */ # define ENUM_BITFIELD( enum_type ) unsigned # define ENUM_TYPE( enum_sp, enum_ty ) enum_ty # define NAME_CONFLICT( name ) _/**/name # define DOTDOTDOT ... # define _VOID_ /* anachronism */ # define CONST const typedef void (*_PFV_)(); typedef int (*_PFI_)(); #elif defined(__STDC__) /* * Definitions for ANSI C */ # define EXTERN_FUNCTION( rtn, args ) rtn args # define STRUCT_TAG( tag_name ) tag_name # define ENUM_BITFIELD( enum_type ) unsigned # define ENUM_TYPE( enum_sp, enum_ty ) enum_sp enum_ty # define NAME_CONFLICT( name ) name # define DOTDOTDOT ... # define _VOID_ void # define CONST #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 STRUCT_TAG( tag_name ) tag_name # define ENUM_BITFIELD( enum_type ) enum_type # define ENUM_TYPE( enum_sp, enum_ty ) enum_sp enum_ty # define NAME_CONFLICT( name ) name # define DOTDOTDOT # define _VOID_ /* VOID is only used where it disappears anyway */ # define CONST #endif /* Which type of C/C++ compiler are we using? */ #endif /* ~defined(C_VARIETIES_H) */ #endif /* defined(XV_C_TYPES_H) */