From: hbf@durin.uio.no (Hallvard B Furuseth)
Subject: Re: Macros for ANSI prototypes
Organization: University of Oslo, Norway
	<1992Aug12.051707.17509@organpipe.uug.arizona.edu>
Date: Fri, 14 Aug 1992 21:05:30 GMT

In article <1992Aug11.075855.13519@elroy.jpl.nasa.gov>, hyc@hanauma (Howard Chu) writes:
>Well, since the topic has risen up again, here's a cheap way to write code
>that works for either ANSI or K&R compilers...
>##### cut here #####
>/*
> * ansi.h - macros for declaring functions and arguments with or without
> * ANSI C prototypes. The __DECL macro is used to declare functions with
> * prototypes. The __DEFN macro is used to actually define the functions.

Isn't the __ symbols reserved for the compiler?  What do you do when you
stumble over a compiler which uses __DEFN for some assemby nonsense?

Here is another version.  I'm sure we are a lot of people who have been
reinventing the wheel, is there more commonly used wheel out there?


In article <1992Aug12.051707.17509@organpipe.uug.arizona.edu> dave@cs.arizona.edu (Dave Schaumann) writes:
> In stead of obfuscating your code with macros that turn on and off
> functio prototypes as the particular compiler requires, wouldn't it be
> better to simply include one of the tools freely available to
> automatically massage prototyped code into K&R acceptability.

And while working on this source tree whith both C++ and traditional C
files I'd need a different include-directory to build the C headers in,
'make' must re-install there after every change to the C++ headers, and
it gets worse if I want to test a change in one package before
installing the .h files.
I prefer an ansidef.h file.  Or better cooperating compilers, of course.


/* ansidef.h -- compatibility macros for C++ / ANSI C / traditional C
 *
 * Usage examples:
 *   IF_CPLUSPLUS(extern "C" {, EMPTY_ARG) / * anti-#if fanatics * /
 *   extern int printf ARGDCL((CONST char *, ...));
 *   extern VOIDFN foo ARGDCL((VOIDDATA *, int)), bar (NOARGS);
 *   IF_CPLUSPLUS(}, EMPTY_ARG)
 *   VOIDFN foo ARGDEF((a,b), VOIDDATA *a ARG int b) { bar(); return VOIDVAL; }
 *   #if IF_ANSI(1,0)		/ * Safer than ie __STDC__ || __cplusplus * /
 *				/ * because it matches what ansidef does  * /
 *   #  include <stdarg.h>
 *   #else
 *   #  include <varargs.h>	/ * Sorry, varargs is not really portable * /
 *   #endif
 *   int xprintf VA_VARGDEF((fmt, va_alist), CONST char *fmt)
 *	{...VA_START(ap,fmt)...}
 *
 * Please add to this file to rope in more machine types and compilers.
 * Hallvard B Furuseth <hbf@usit.uio.no>, Mar 1992
 */

#ifndef ANSIDEF_H_
#define ANSIDEF_H_

/* Give this to preprocessors that do not grok empty macro args */
#define EMPTY_ARG

#ifdef __cplusplus
#  define IF_CPLUSPLUS(cplpl,c)	cplpl
#  define INLINE		inline	/* *ATTEMPT* to make inline function */
#else
#  define IF_CPLUSPLUS(cplpl,c)	c
#if __GNUC__
#  define INLINE		static __inline__
#else
#  define INLINE		static	/* Better than nothing */
#endif
#endif /* C++ */

#if defined(__STDC__) || defined(__cplusplus)
#  define IF_ANSI(ansi,trad)	ansi
#  define ARGDCL(args)		args	/* Arguments in function declaration */
#  define ARGDEF(args,defs)	(defs)	/* Arguments in function definition  */
#  define ARG			,	/* Argument separator in definitions */
#  define NOARGS		void	/* Arg to function with no arguments */
#  define VA_ARGDEF(args,defs)	(defs, ...) /* Args to variable arguments fn */
#  define VA_START		va_start /* Use this instead of va_start */
#  define CONST			const	/* Qualifiers - need a type as well  */
#  define SIGNED		signed
#  define VOLATILE		volatile
#  define HAS_VOID		1
#else
#  define IF_ANSI(ansi,trad)	trad
#  define ARGDCL(args)		()
#  define ARGDEF(args,defs)	args defs;
#  define ARG			;
#  define NOARGS
#  define VA_ARGDEF(args,defs)	args defs; va_dcl
#  define VA_START(ptr,last)	va_start((ptr))
#  define CONST
#  define SIGNED
#  define VOLATILE
#endif /* ANSI/C++ */

#if HAS_VOID ||\
	defined(ultrix) || defined(sun) ||\
	defined(__ultrix__) || defined(__sun__) /* gcc versions */
#  define HAS_VOID		1	/* True if 'void' exists */
#  define VOIDDATA		void	/* Data type of void* "contents"  */
#  define VOIDFN		void	/* Return type for void functions */
#  define VOIDVAL			/* Return value for void functions */
#else
#  define VOIDDATA		char
#  define VOIDFN		int
#  define VOIDVAL		0
#endif /* HAS_VOID */

#endif /* ANSIDEF_H_ */
--

Hallvard