[PATCH] Fix hpux10 string to real conversion defficiences
FX Coudert
fxcoudert@gmail.com
Fri Apr 11 13:56:00 GMT 2008
> 2008-04-10 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
>
> PR fortran/35667
> * acinclude.m4 (LIBGFOR_CHECK_FOR_BROKEN_STRTOF,
> LIBGFOR_CHECK_FOR_BROKEN_STRTOD,
> LIBGFOR_CHECK_FOR_BROKEN_STRTOLD): New
> check macros.
> * configure.ac: Use new check macros.
> * configure: Rebuilt.
> * config.h.in: Rebuilt.
> * io/read.c (nan_p, inf_p, gfc_strtof, gfc_strtod, gfc_strtold): New
> functions.
> (convert_real): Use new functions.
In addition to Ralf's comment (and I think the package prefix to add
to the variables should be "libgfor"), I have the following remarks
and questions.
Thanks for this great patch,
FX
> +static int nan_p (const char *) __attribute__((unused));
> +static int inf_p (const char *) __attribute__((unused));
> +#if defined(HAVE_STRTOLD)
> +static long double gfc_strtold (const char *, char **)
> __attribute__((unused));
> +#endif
We tend to avoid forward definitions unless they are required. Can
you move the "__attribute__((unused))" to the function itself and
remove those?
> /* convert_real()-- Convert a character representation of a floating
> * point number to the machine number. Returns nonzero if there is a
> - * range problem during conversion. TODO: handle not-a-numbers and
> - * infinities. */
> + * range problem during conversion. */
> +
> +/* Return 1 if the string S matches the string "nan" irrespective
> of case;
> + otherwise return 0. */
The comment about convert_real() should stay just above convert_real
() itself.
> +static int
> +nan_p (const char *s)
~/devel/gfortran/trunk/libgfortran/io $ grep '^is' * | wc -l
5
~/devel/gfortran/trunk/libgfortran/io $ grep '_p\>' * | wc -l
0
I guess that speaks for itself :) We don't have any *_p functions,
but we have is_* functions in libgfortran. I suggest naming them
is_nan() and is_inf().
> +{
> + if (*s != 'n' && *s != 'N')
> + return 0;
> +
> + s++;
> + if (*s != 'a' && *s != 'A')
> + return 0;
> +
> + s++;
> + if (*s != 'n' && *s != 'N')
> + return 0;
> +
> + s++;
> + if (*s != 0)
> + return 0;
This is a really open question to both you and Jerry: in the case of
"NaN " (ie a space following the NaN), do we still do the right thing
here?
> +static float
> +gfc_strtof (const char *s, char **p)
> +{
> +#if ((defined(HAVE_STRTOF) && defined(HAVE_BROKEN_STRTOF)) \
> + || defined(HAVE_BROKEN_STRTOD))
> + const char *s1 = s;
> + int plus = 1;
> +
> + if (*s1 == '+')
> + s1++;
> + else if (*s == '-')
> + {
> + s1++;
> + plus = 0;
> + }
> +
> + if (nan_p (s1))
> + return plus ? __builtin_nanf ("") : -__builtin_nanf ("");
> + else if (inf_p (s1))
> + return plus ? __builtin_inff () : -__builtin_inff ();
> +#endif
If you have HAVE_STRTOF and HAVE_BROKEN_STRTOF, you end up with the
following "return" being dead code. I suggest changing the above
"#endif" into an "#else" (and adding another "#endif" at the end of
the function).
> +
> +#if defined(HAVE_STRTOF)
> + return strtof (s, p);
> +#else
> + return (float) strtod (s, p);
> +#endif
> +}
Same thing for gfc_strtod() and gfc_strtold().
FX
--
François-Xavier Coudert
http://www.homepages.ucl.ac.uk/~uccafco/
More information about the Fortran
mailing list