/*------------------------->  ANSI C - headerfile  <-------------------------*/
/* Copyright (C) 1994 by International Computer Science Institute            */
/* This file is part of the GNU Sather library. It is free software; you may */
/* redistribute  and/or modify it under the terms of the GNU Library General */
/* Public  License (LGPL)  as published  by the  Free  Software  Foundation; */
/* either version 2 of the license, or (at your option) any later version.   */
/* This  library  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 Doc/LGPL for more details.       */
/* The license text is also available from:  Free Software Foundation, Inc., */
/* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA                     */
/*------------>  Please email comments to <bug-sather@gnu.org>  <------------*/

/* Have we already been here? */
#ifndef FLOATMATH
#define FLOATMATH 1
#include <float.h>

/* XPG-defined constants not supplied by MS Visual C++ include files */
#if defined(__CYGWIN32__)
# define M_E        2.7182818284590452354
# define M_LOG2E    1.4426950408889634074
# define M_LOG10E   0.43429448190325182765
# define M_LN2      0.69314718055994530942
# define M_LN10     2.30258509299404568402
# define M_PI       3.14159265358979323846
# define M_PI_2     1.57079632679489661923
# define M_PI_4     0.78539816339744830962
# define M_1_PI     0.31830988618379067154
# define M_2_PI     0.63661977236758134308
# define M_2_SQRTPI 1.12837916709551257390
# define M_SQRT2    1.41421356237309504880
# define M_SQRT1_2  0.70710678118654752440
#endif

#ifdef SUNOS5
double signaling_nan(int);
double infinity();
#endif

/*
* This file is included by Sather/System/header.h
* at the head of each compiler-generated header file.
*
* If the system supports single-precision library calls, these are used.
* Otherwise the floats are converted to double and back afterwards.
*/

#if defined(ASSIGNFLOAT)
/* WITH single-precision library */

#if defined(SPARC) && defined (SUNOS4)

/* Fix a problem in the <math.h> in SunOS 4 on the Sparc.
 * This otherwise causes annoying warning messages during compiling.
 * If you have problems with this redefinition, delete it and ignore
 * the warning messages.
 *
 * This is how the original definition should look like:
 * #define	ASSIGNFLOAT(x,y)	{ union {double _d; float _f } _kluge; _kluge._d = (y); x = _kluge._f; }
 */

#undef ASSIGNFLOAT
#define	ASSIGNFLOAT(x,y)	{ union {double _d; float _f;} _kluge; _kluge._d = (y); x = _kluge._f; }

#endif	/* defined(SPARC) && defined (SUNOS4) */

#define _FM_F(name)	\
	static FLT r_##name()\
	{float f; ASSIGNFLOAT(f,r_##name##_()); return f;}

#define _FM_F_I(name)	\
	static FLT r_##name(INT i)\
	{float f; ASSIGNFLOAT(f,r_##name##_(&i)); return f;}

#define _FM_F_F(name)	\
	static FLT r_##name(FLT f)\
	{ASSIGNFLOAT(f,r_##name##_(&f)); return f;}

#define _FM_F_FF(name)	\
	static FLT r_##name(FLT f,FLT g)\
	{ASSIGNFLOAT(f,r_##name##_(&f,&g)); return f;}

#define _FM_F_FI(name)	\
	static FLT r_##name(FLT f,INT i)\
	{ASSIGNFLOAT(f,r_##name##_(&f,&i)); return f;}

#define _FM_F_IF(name)	\
	static FLT r_##name(INT i,FLT f)\
	{ASSIGNFLOAT(f,r_##name##_(&i,&f)); return f;}

#define _FM_B_F(name)	\
	static BOOL ir_##name(FLT f)\
	{return ir_##name##_(&f);}

#define _FM_I_F(name)	\
	static INT ir_##name(FLT f)\
	{return ir_##name##_(&f);}

#define _FM_V_FP(name)	\
	static void r_##name(FLT f, FLT g[])\
	{r_##name##_(&f,g,g+1);}

#else
/* WITHOUT single-precision library */

#define _FM_F(name)	static FLT r_##name() {return name##();}
#define _FM_F_I(name)	static FLT r_##name(INT i) {return name##(i);}
#define _FM_F_F(name)	static FLT r_##name(FLT f) {return name##(f);}
#define _FM_F_FF(name)	static FLT r_##name(FLT f,FLT g) {return name##(f,g);}
#define _FM_F_FI(name)	static FLT r_##name(FLT f,INT i) {return name##(f,i);}
#define _FM_F_IF(name)	static FLT r_##name(INT i,FLT f) {return name##(i,f);}
#define _FM_B_F(name)	static BOOL ir_##name(FLT f) {return ir_##name##(f);}
#define _FM_I_F(name)	static INT ir_##name(FLT f) {return ir_##name##(f);}
#define _FM_V_FP(name)	static void r_##name(FLT f, FLT g[])\
			{double a,b; sincos(f,&a,&b); g[0]=a; g[1]=b;}

#endif

/* Nothing should go behind this #endif */
#endif
