From 1ff8f50f2f9dae5a190d21ef1ba54a70b5984d3b Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 16 Feb 2005 15:08:29 +0000 Subject: [PATCH] fixed problems with parse_float() (fd.o bug 2520) --- src/mesa/shader/arbprogparse.c | 75 ++++++++++++++++++++++------------ 1 file changed, 48 insertions(+), 27 deletions(-) diff --git a/src/mesa/shader/arbprogparse.c b/src/mesa/shader/arbprogparse.c index 10f0a1b3244..4e92d5017e3 100644 --- a/src/mesa/shader/arbprogparse.c +++ b/src/mesa/shader/arbprogparse.c @@ -686,39 +686,60 @@ parse_integer (GLubyte ** inst, struct arb_program *Program) } /** - */ -static GLfloat -parse_float (GLubyte ** inst, struct arb_program *Program) + Accumulate this string of digits, and return them as + a large integer represented in floating point (for range). + If scale is not NULL, also accumulates a power-of-ten + integer scale factor that represents the number of digits + in the string. +*/ +static GLdouble +parse_float_string(GLubyte ** inst, struct arb_program *Program, GLdouble *scale) { - GLint tmp[5], denom; - GLuint leading_zeros =0; - GLfloat value = 0; - - tmp[1] = parse_integer (inst, Program); /* This is the integer portion of the number */ + GLdouble value = 0.0; + GLdouble oscale = 1.0; - /* Now we grab the fractional portion of the number (the digits after - * the .). We can have leading 0's here, which parse_integer will ignore, - * so we'll check for those first - */ - while ((**inst == '0') && ( *(*inst+1) != 0)) - { - leading_zeros++; - (*inst)++; + if (**inst == 0) { /* this string of digits is empty-- do nothing */ + (*inst)++; + } + else { /* nonempty string-- parse out the digits */ + while (isdigit(**inst)) { + GLubyte digit = *((*inst)++); + value = value * 10.0 + (GLint) (digit - '0'); + oscale *= 10.0; + } + assert(**inst == 0); /* integer string should end with 0 */ + (*inst)++; /* skip over terminating 0 */ + Program->Position = parse_position(inst); /* skip position (from integer) */ } - tmp[2] = parse_integer (inst, Program); /* This is the fractional portion of the number */ - tmp[3] = parse_sign (inst); /* This is the sign of the exponent */ - tmp[4] = parse_integer (inst, Program); /* This is the exponent */ + if (scale) + *scale = oscale; + return value; +} - value = (GLfloat) tmp[1]; - denom = 1; - while (denom < tmp[2]) - denom *= 10; - denom *= (GLint) _mesa_pow( 10, leading_zeros ); - value += (GLfloat) tmp[2] / (GLfloat) denom; +/** + Parse an unsigned floating-point number from this stream of tokenized + characters. Example floating-point formats supported: + 12.34 + 12 + 0.34 + .34 + 12.34e-4 + */ +static GLfloat +parse_float (GLubyte ** inst, struct arb_program *Program) +{ + GLint exponent; + GLdouble whole, fraction, fracScale = 1.0; - value *= (GLfloat) _mesa_pow (10, (GLfloat) tmp[3] * (GLfloat) tmp[4]); + whole = parse_float_string(inst, Program, 0); + fraction = parse_float_string(inst, Program, &fracScale); + + /* Parse signed exponent */ + exponent = parse_integer(inst, Program); /* This is the exponent */ - return value; + /* Assemble parts of floating-point number: */ + return (GLfloat) ((whole + fraction / fracScale) * + _mesa_pow(10.0, (GLfloat) exponent)); } -- 2.30.2