#include  <math.h>

extern int errno;

/* This math function file is to make up for deficiencies in some
 * library math functions.  The following are missing for some vendors:
 *
 *   (double) asinh( double )   inverse hyperbolic sin
 *   (double) acosh( double )   inverse hyperbolic cos
 *   (double) atanh( double )   inverse hyperbolic tan
 *   (double) cbrt(  double )   cubic root
 *   (double) rint(  double )   nearest rounded integer
 *   (double) trunc( double )   truncated integer
 *
 * For Linux, it's trunc.
 *
 * Some versions of SunOS lack trunc().
 */

#ifdef NOGAMMA
double lgamma(double x)
{
	double const cof[] = { 76.18009173E0, -86.50532033E0, 24.01409822E0,
			  -1.231739516E0, 0.120858003E-2, -0,536382E-5 } ;
	double const stp = 2.50662827465, fpf = 5.5, pi=3.1415926535897932;

	int i;
	double tmp,ser;

	if (x < 0.5)
	return log(fabs(pi/sin(pi*(1.-x)))) - lgamma(1.-x);
	else
	{
	x = x - 1.0;
	tmp = x + fpf;
	tmp = (x+.5)*log(tmp)-tmp;
	ser = 1.0;
	for (i=0; i<6; i++)
	{
		x = x + 1.0;
		ser += cof[i]/x;
	}
	return tmp+log(stp*ser);
	}
}
#endif

#ifdef NORINT
double rint(double x)
{
	 double diff;

	 diff = x - floor(x);
	 if (diff >= 0.5) {
	 	return(ceil(x));
	 }
	 else {
	   	return(floor(x));
	 }
}
#endif

#ifdef NOTRUNC
double trunc(double x)
{
	if (x < 0)
		return(ceil(x));
	else
		return(floor(x));
}
#endif

#ifdef NOCBRT
#define  ONE_THIRD 0.3333333333333333333333333333
double cbrt(double x)
{
	double y, val, pow();

	y = fabs(x);
	val = pow(y, ONE_THIRD) * (x/y);
	return(val);
}
#endif

#ifdef NOHYP_TRIGO
double acosh(double x)
{
	double val;

	val = log(x) + log(1.0 + sqrt(1.0 - 1.0/(x*x)));
	return(val);
}

double asinh(double x)
{
	double val;

	if(x == 0.0)
		return(0.0);
	val = log(fabs(x)) + log(1.0 + sqrt(1.0 + 1.0/(x*x)));
	if(x < 0)
		val = -val;
	return(val);
}

double atanh(double x)
{
	double val;

	val = 0.5 * log((1.0 + x)/(1.0 - x));
	return(val);
}

#endif

#ifdef NOSTRSTR
/*
 *  For systems not having this function.
 */

#include <string.h>

#ifndef NULL
#define NULL 0
#endif

char *strstr(s1, s2)
register char *s1;
register char *s2;
{
  register int i;
  register int len1 = strlen (s1);
  register int len2 = strlen (s2);

  for (i = 0; (len1 - i) >= len2; i++)
	  if (strncmp(&s1[i], s2, len2) == 0)
		  return (s1 + i);
  return ((char *)NULL);
}

#endif
