
#line 1 "hb-number-parser.rl"
/*
 * 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>


#line 37 "hb-number-parser.hh"
static const unsigned char _double_parser_trans_keys[] = {
	0u, 0u, 43u, 57u, 46u, 57u, 48u, 57u, 43u, 57u, 48u, 57u, 48u, 101u, 48u, 57u, 
	46u, 101u, 0
};

static const char _double_parser_key_spans[] = {
	0, 15, 12, 10, 15, 10, 54, 10, 
	56
};

static const unsigned char _double_parser_index_offsets[] = {
	0, 0, 16, 29, 40, 56, 67, 122, 
	133
};

static const char _double_parser_indicies[] = {
	0, 1, 2, 3, 1, 4, 4, 
	4, 4, 4, 4, 4, 4, 4, 4, 
	1, 3, 1, 4, 4, 4, 4, 4, 
	4, 4, 4, 4, 4, 1, 5, 5, 
	5, 5, 5, 5, 5, 5, 5, 5, 
	1, 6, 1, 7, 1, 1, 8, 8, 
	8, 8, 8, 8, 8, 8, 8, 8, 
	1, 8, 8, 8, 8, 8, 8, 8, 
	8, 8, 8, 1, 5, 5, 5, 5, 
	5, 5, 5, 5, 5, 5, 1, 1, 
	1, 1, 1, 1, 1, 1, 1, 1, 
	1, 9, 1, 1, 1, 1, 1, 1, 
	1, 1, 1, 1, 1, 1, 1, 1, 
	1, 1, 1, 1, 1, 1, 1, 1, 
	1, 1, 1, 1, 1, 1, 1, 1, 
	1, 9, 1, 8, 8, 8, 8, 8, 
	8, 8, 8, 8, 8, 1, 3, 1, 
	4, 4, 4, 4, 4, 4, 4, 4, 
	4, 4, 1, 1, 1, 1, 1, 1, 
	1, 1, 1, 1, 1, 9, 1, 1, 
	1, 1, 1, 1, 1, 1, 1, 1, 
	1, 1, 1, 1, 1, 1, 1, 1, 
	1, 1, 1, 1, 1, 1, 1, 1, 
	1, 1, 1, 1, 1, 9, 1, 0
};

static const char _double_parser_trans_targs[] = {
	2, 0, 2, 3, 8, 6, 5, 5, 
	7, 4
};

static const char _double_parser_trans_actions[] = {
	0, 0, 1, 0, 2, 3, 0, 4, 
	5, 0
};

static const int double_parser_start = 1;
static const int double_parser_first_final = 6;
static const int double_parser_error = 0;

static const int double_parser_en_main = 1;


#line 70 "hb-number-parser.rl"


/* 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;
  
#line 142 "hb-number-parser.hh"
	{
	cs = double_parser_start;
	}

#line 147 "hb-number-parser.hh"
	{
	int _slen;
	int _trans;
	const unsigned char *_keys;
	const char *_inds;
	if ( p == pe )
		goto _test_eof;
	if ( cs == 0 )
		goto _out;
_resume:
	_keys = _double_parser_trans_keys + (cs<<1);
	_inds = _double_parser_indicies + _double_parser_index_offsets[cs];

	_slen = _double_parser_key_spans[cs];
	_trans = _inds[ _slen > 0 && _keys[0] <=(*p) &&
		(*p) <= _keys[1] ?
		(*p) - _keys[0] : _slen ];

	cs = _double_parser_trans_targs[_trans];

	if ( _double_parser_trans_actions[_trans] == 0 )
		goto _again;

	switch ( _double_parser_trans_actions[_trans] ) {
	case 1:
#line 39 "hb-number-parser.rl"
	{ neg = true; }
	break;
	case 4:
#line 40 "hb-number-parser.rl"
	{ exp_neg = true; }
	break;
	case 2:
#line 42 "hb-number-parser.rl"
	{
	value = value * 10. + ((*p) - '0');
}
	break;
	case 3:
#line 45 "hb-number-parser.rl"
	{
	if (likely (frac <= MAX_FRACT / 10))
	{
	  frac = frac * 10. + ((*p) - '0');
	  ++frac_count;
	}
}
	break;
	case 5:
#line 52 "hb-number-parser.rl"
	{
	if (likely (exp * 10 + ((*p) - '0') <= MAX_EXP))
	  exp = exp * 10 + ((*p) - '0');
	else
	  exp_overflow = true;
}
	break;
#line 205 "hb-number-parser.hh"
	}

_again:
	if ( cs == 0 )
		goto _out;
	if ( ++p != pe )
		goto _resume;
	_test_eof: {}
	_out: {}
	}

#line 116 "hb-number-parser.rl"


  *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 */
