/* 
   Copyright 1994-2003 Free Software Foundation, Inc.

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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 the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with this library; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 
   USA

   You may contact the author at:

   mailto::camille@bluegrass.net

   or by snail mail at:

   David Lindauer
   850 Washburn Ave Apt 99
   Louisville, KY 40222
*/
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <time.h>
#include <wchar.h>
#include <locale.h>
#include "libp.h"

char * _RTL_FUNC ecvt(double val, int len, int *decimal, int *sign)
{
	char buf[256],*p = buf, *q;
	int i;
	char *ecvtbuf = __getRtlData()->ecvt_buf;
	int l;
	if (!len || !decimal || !sign)
	{
		errno = EINVAL;
		return NULL;
	}
	memset(ecvtbuf, 0, 100);
	sprintf(buf, "%.40f", val);
	if (*p == '-')
	{
		*sign = 1;
		p++;
	}
	else
		*sign = 0;
	for (i=0; i < 100; i++)
	{
		if (p[i] == '.')
		{
			*decimal = i;
			strcpy(p+i, p+i+1);
			break;
		}
	}
		
	q = strchr(ecvtbuf, 'e');
	if (!q)
		q = strchr(ecvtbuf, 'E');
	if (q)
		*q = 0;
	if (len < 99)
		if (p[len])
		{
			int n = p[len];
			if (n >= '5')
			{
				q = p + len -1;
				while (q >= p)
				{
					if (++(*q) <= '9')
						break;
					*q--='0';
				}
				if (q < p)
				{
					memmove(p+1, p, len);
					p[0] = '1';
					(*decimal)++;
				}
			}
			p[len] = 0;
		}
	return p;
	
}
char * _RTL_FUNC fcvt(double val, int len, int *decimal, int *sign)
{
	char buf[64], *q;
	char *ecvtbuf = __getRtlData()->ecvt_buf;
	char *p = ecvtbuf;
	int i = 0;
	if (!len || !decimal || !sign)
	{
		errno = EINVAL;
		return NULL;
	}
	memset(ecvtbuf, 0, 100);
	if (len > 40)
		len = 40;
	sprintf(buf, "%%.%df", len);
	sprintf(ecvtbuf, buf, val);
	if (*p == '-')
	{
		*sign = 1;
		p++;
	}
	else *sign = 0;
	for (i=0; i < 100; i++)
	{
		if (p[i] == '.')
		{
			*decimal = i;
			strcpy(p+i, p+i+1);
			break;
		}
	}
	q = strchr(ecvtbuf, 'e');
	if (!q)
		q = strchr(ecvtbuf, 'E');
	if (q)
		*q = 0;
	return p;
}
char * _RTL_FUNC gcvt(double val, int len, char *result)
{
	char buf[256], *p, *q;
	int i;
	if (!len)
	{
		errno = EINVAL;
		return NULL;
	}
	sprintf(buf,"%.40f", val);
	p = strchr(buf,'.');
	if (p && p-buf-1-(buf[0]=='-') > len)
	{
		sprintf(buf,"%.40e", val);
	}
	q = strchr(buf,'e');
	if (!q)
	{
		q = strchr(buf,'E');
		if (!q)
			q = buf + strlen(buf);
	}
	i = q - buf - 1 - (buf[0] == '-');
	if (i > len)
	{
		i = i - len;
		p = q - i + 1;
		if (*p >= '5')
		{
			p--;
			while (p >= buf)
			{
				if (*p != '.' && *p != '-')
					if (++(*p) <= '9')
						break;
				*p-- = '0';
			}
			if (p < buf)
			{
				p = buf + (buf[0] == '-');
				memmove(p+1, p, 250);
				p[0] = '1';
				q++;
				i++;
			}
		}
		strcpy(q - i, q);
	}
	strcpy(result, buf);
	return result;
}

char * _RTL_FUNC _ecvt(double val, int len, int *decimal, int *sign)
{
	return ecvt(val, len, decimal, sign);
}
char * _RTL_FUNC _fcvt(double val, int len, int *decimal, int *sign)
{
	return fcvt(val, len, decimal, sign);
}
char * _RTL_FUNC _gcvt(double val, int len, char * result)
{
	return gcvt(val, len, result);
}
