PATCH: (for) Re: Portability of idiom

Loren James Rittle rittle@latour.rsch.comm.mot.com
Wed Jan 30 16:47:00 GMT 2002


>>> FAIL: 26_numerics/complex_inserters_extractors.cc execution test
>>> FAIL: 27_io/istream_sentry.cc execution test

>> Cool let's fix this up!

> OK, I will present a patch later today which merely changes the check
> of errno == 0 to be "errno not have any value set by called C
> library function as spec'd in C90/C99".

Rebuilt libstdc++-v3 from scratch on i386-unknown-freebsd5.0 and
i386-unknown-freebsd4.4.  Fixes both quoted test cases on the first
machine with no regressions.  I reviewed FreeBSD, Solaris 2.7 and OSF1
man pages and ISO C99.  Unfortunately, the Solaris man page says:

``If no conversion could be performed, strtol() and strtoll() return 0
  and errno may be set to EINVAL.'' (OSF1 similar)

Fortunately, both Solaris and OSF will only ever actually set this
non-standard errno, if base is out of range.  We tightly control the
base setting in the library thus this difference need not be
conditionally checked per port (Solaris sets __sanity to __s anyways).
Since ERANGE is the only value mentioned in the specification, I check
for it alone.

In any event, given the nature of the change, I also rebuilt and
checked on sparc-sun-solaris2.7 (looking good) and alphaev67-dec-osf5.1
(26_numerics/complex_inserters_extractors.cc and 28 other tests still
fail for independent reasons) without regression.

I shant touch libstdc++-v3/config/locale/c_locale_gnu.cc since I
presume it knows all about the library implementation.  It is using
special GNU libc entry points.

Installed on mainline.  (Strictly speaking, not a regression from 3.0
thus should not be moved to branch.)

	* config/locale/c_locale_generic.cc: Check errno for ERANGE
	instead of non-zero to aid portability.

Index: libstdc++-v3/config/locale/c_locale_generic.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/config/locale/c_locale_generic.cc,v
retrieving revision 1.6
diff -c -r1.6 c_locale_generic.cc
*** c_locale_generic.cc	2002/01/23 16:20:46	1.6
--- c_locale_generic.cc	2002/01/30 22:40:02
***************
*** 48,54 ****
  	char* __sanity;
  	errno = 0;
  	long __l = strtol(__s, &__sanity, __base);
! 	if (__sanity != __s && *__sanity == '\0' && errno == 0)
  	  __v = __l;
  	else
  	  __err |= ios_base::failbit;
--- 48,54 ----
  	char* __sanity;
  	errno = 0;
  	long __l = strtol(__s, &__sanity, __base);
! 	if (__sanity != __s && *__sanity == '\0' && errno != ERANGE)
  	  __v = __l;
  	else
  	  __err |= ios_base::failbit;
***************
*** 65,71 ****
  	  char* __sanity;
  	  errno = 0;
  	  unsigned long __ul = strtoul(__s, &__sanity, __base);
!           if (__sanity != __s && *__sanity == '\0' && errno == 0)
  	    __v = __ul;
  	  else
  	    __err |= ios_base::failbit;
--- 65,71 ----
  	  char* __sanity;
  	  errno = 0;
  	  unsigned long __ul = strtoul(__s, &__sanity, __base);
!           if (__sanity != __s && *__sanity == '\0' && errno != ERANGE)
  	    __v = __ul;
  	  else
  	    __err |= ios_base::failbit;
***************
*** 83,89 ****
  	  char* __sanity;
  	  errno = 0;
  	  long long __ll = strtoll(__s, &__sanity, __base);
!           if (__sanity != __s && *__sanity == '\0' && errno == 0)
  	    __v = __ll;
  	  else
  	    __err |= ios_base::failbit;
--- 83,89 ----
  	  char* __sanity;
  	  errno = 0;
  	  long long __ll = strtoll(__s, &__sanity, __base);
!           if (__sanity != __s && *__sanity == '\0' && errno != ERANGE)
  	    __v = __ll;
  	  else
  	    __err |= ios_base::failbit;
***************
*** 100,106 ****
  	  char* __sanity;
  	  errno = 0;
  	  unsigned long long __ull = strtoull(__s, &__sanity, __base);
!           if (__sanity != __s && *__sanity == '\0' && errno == 0)
  	    __v = __ull;
  	  else
  	    __err |= ios_base::failbit;
--- 100,106 ----
  	  char* __sanity;
  	  errno = 0;
  	  unsigned long long __ull = strtoull(__s, &__sanity, __base);
!           if (__sanity != __s && *__sanity == '\0' && errno != ERANGE)
  	    __v = __ull;
  	  else
  	    __err |= ios_base::failbit;
***************
*** 124,130 ****
  #else
  	  float __f = static_cast<float>(strtod(__s, &__sanity));
  #endif
!           if (__sanity != __s && *__sanity == '\0' && errno == 0)
  	    __v = __f;
  	  else
  	    __err |= ios_base::failbit;
--- 124,130 ----
  #else
  	  float __f = static_cast<float>(strtod(__s, &__sanity));
  #endif
!           if (__sanity != __s && *__sanity == '\0' && errno != ERANGE)
  	    __v = __f;
  	  else
  	    __err |= ios_base::failbit;
***************
*** 144,150 ****
  	  char* __sanity;
  	  errno = 0;
  	  double __d = strtod(__s, &__sanity);
!           if (__sanity != __s && *__sanity == '\0' && errno == 0)
  	    __v = __d;
  	  else
  	    __err |= ios_base::failbit;
--- 144,150 ----
  	  char* __sanity;
  	  errno = 0;
  	  double __d = strtod(__s, &__sanity);
!           if (__sanity != __s && *__sanity == '\0' && errno != ERANGE)
  	    __v = __d;
  	  else
  	    __err |= ios_base::failbit;
***************
*** 165,171 ****
  	  char* __sanity;
  	  errno = 0;
  	  long double __ld = strtold(__s, &__sanity);
!           if (__sanity != __s && *__sanity == '\0' && errno == 0)
  	    __v = __ld;
  #else
  	  typedef char_traits<char>::int_type int_type;
--- 165,171 ----
  	  char* __sanity;
  	  errno = 0;
  	  long double __ld = strtold(__s, &__sanity);
!           if (__sanity != __s && *__sanity == '\0' && errno != ERANGE)
  	    __v = __ld;
  #else
  	  typedef char_traits<char>::int_type int_type;



More information about the Libstdc++ mailing list