/*
 * Copyright © 2019  Ebrahim Byagowi
 *
 *  This is part of HarfBuzz, a text shaping library.
 *
 * Permission is hereby granted, without written agreement and without
 * license or royalty fees, to use, copy, modify, and distribute this
 * software and its documentation for any purpose, provided that the
 * above copyright notice and the following two paragraphs appear in
 * all copies of this software.
 *
 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 *
 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 *
 */

#ifndef HB_NUMBER_PARSER_HH
#define HB_NUMBER_PARSER_HH

#include "hb.hh"

#include <float.h>

%%{

machine double_parser;
alphtype unsigned char;
write data;

action see_neg { neg = true; }
action see_exp_neg { exp_neg = true; }

action add_int  {
	value = value * 10. + (fc - '0');
}
action add_frac {
	if (likely (frac <= MAX_FRACT / 10))
	{
	  frac = frac * 10. + (fc - '0');
	  ++frac_count;
	}
}
action add_exp  {
	if (likely (exp * 10 + (fc - '0') <= MAX_EXP))
	  exp = exp * 10 + (fc - '0');
	else
	  exp_overflow = true;
}

num = [0-9]+;

main := (
	(
		(('+'|'-'@see_neg)? num @add_int) ('.' num @add_frac)?
		|
		(('+'|'-'@see_neg)? '.' num @add_frac)
	)
	(('e'|'E') (('+'|'-'@see_exp_neg)? num @add_exp))?
);

}%%

/* Works only for n < 512 */
static inline double
_pow10 (unsigned int exponent)
{
  static const double _powers_of_10[] =
  {
    1.0e+256,
    1.0e+128,
    1.0e+64,
    1.0e+32,
    1.0e+16,
    1.0e+8,
    10000.,
    100.,
    10.
  };
  unsigned int mask = 1 << (ARRAY_LENGTH (_powers_of_10) - 1);
  double result = 1;
  for (const double *power = _powers_of_10; mask; ++power, mask >>= 1)
    if (exponent & mask) result *= *power;
  return result;
}

static inline double
strtod_rl (const char *buf, char **end_ptr)
{
  const char *p, *pe;
  double value = 0;
  double frac = 0;
  double frac_count = 0;
  unsigned int exp = 0;
  bool neg = false, exp_neg = false, exp_overflow = false;
  const unsigned long long MAX_FRACT = 0xFFFFFFFFFFFFFull; /* 1^52-1 */
  const unsigned int MAX_EXP = 0x7FFu; /* 1^11-1 */
  p = buf;
  pe = p + strlen (p);

  while (p < pe && ISSPACE (*p))
    p++;

  int cs;
  %%{
    write init;
    write exec;
  }%%

  *end_ptr = (char *) p;

  if (frac_count) value += frac / _pow10 (frac_count);
  if (neg) value *= -1.;

  if (unlikely (exp_overflow))
  {
    if (value == 0) return value;
    if (exp_neg)    return neg ? -DBL_MIN : DBL_MIN;
    else            return neg ? -DBL_MAX : DBL_MAX;
  }

  if (exp)
  {
    if (exp_neg) value /= _pow10 (exp);
    else         value *= _pow10 (exp);
  }

  return value;
}

#endif /* HB_NUMBER_PARSER_HH */
