
/* strtod.c */

#include <stdlib.h>
#include <ctype.h>

double 
strtod (const char *nptr, char **endptr)
{
	extern int errno;
  int sign, valid;
  const char *strptr, *saveptr;
  double retval;

	errno=0;
  valid = 0;

  strptr = nptr;

  while (isspace (*strptr))
    strptr++;

  sign = 1;
  if (*strptr == '-')
    {
      sign = -1;
      strptr++;
    }
  else if (*strptr == '+')
    strptr++;

  saveptr = strptr;

  retval = 0.0;
  while (isdigit (*strptr))
    {
      retval = retval * 10 + (*strptr - '0');
      strptr++;
    }

  if (strptr != saveptr)
    valid = 1;

  if (*strptr == '.')
    {
      double frac;
      const char *p;

      ++strptr;

      saveptr = strptr;

      while (isdigit (*strptr))
	strptr++;

      p = strptr;

      frac = 0.0;
      while (--p >= saveptr)
	frac = (frac + (*p - '0')) / 10;

      retval += frac;

      if (strptr != saveptr)
	valid = 1;
    }

  if (valid && tolower (*strptr) == 'e')
    {
      char *endptr;
      double exp;

      strptr++;

      exp = strtol (strptr, &endptr, 10);
      if (endptr != strptr)
	{
	  strptr = endptr;

	  if (exp > 0)
	    {
	      while (exp-- > 0)
		retval *= 10.0;
	    }
	  else if (exp < 0)
	    {
	      while (exp++ < 0)
		retval /= 10.0;
	    }
	}
      else
	strptr--;
    }

  if (endptr != NULL)
    *endptr = (char *) (valid ? strptr : nptr);

  return sign < 0 ? -retval : retval;
}
