incubator-stdcxx-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Martin Sebor <se...@roguewave.com>
Subject Re: svn commit: r646396 - /stdcxx/trunk/src/num_put.cpp
Date Wed, 09 Apr 2008 23:55:44 GMT
faridz@apache.org wrote:
> Author: faridz
> Date: Wed Apr  9 08:10:18 2008
> New Revision: 646396
> 
> URL: http://svn.apache.org/viewvc?rev=646396&view=rev
> Log:
> 2008-04-09  Farid Zaripov  <farid_zaripov@epam.com>
> 
> 	STDCXX-51
> 	* src/num_put.cpp (__rw_isfinite): New function to detect inf and nan values.
> 	(__rw_signbit): New function to detect the sign of floating point value.
> 	(__rw_isinf): New function to detect inf values.
> 	(__rw_isnan): New function to detect nan values.
> 	(__rw_isqnan): New function to detect quiet nan values.
> 	(__rw_issnan): New function to detect signaling nan values.
> 	(__rw_fmat_infinite): New function to format inf and nan values.
> 	(__rw_put_num): Use __rw_isfinite() and __rw_fmat_infinite() to format inf and nan values.

I'm afraid this patch causes a compilation error on Solaris:

CC -c -D_RWSTDDEBUG   -mt -D_RWSTD_SOLARIS_THREADS 
-I/amd/devco/sebor/stdcxx/include 
-I/build/sebor/stdcxx-suncc-5.9_j1-15d-solaris/include  -library=%none 
-g  +w -errtags -erroff=hidef  -KPIC 
/amd/devco/sebor/stdcxx/src/strstream.cpp
"/amd/devco/sebor/stdcxx/src/num_put.cpp", line 122: Error, badfunccp: 
The function "signbit" must have a prototype.
1 Error(s) detected.

Depending on where one looks, the signbit() macro is declared either
in <math.h> or <sunmath.h>

http://docs.sun.com/app/docs/doc/816-5172/signbit-3m?a=view
http://docs.sun.com/source/820-4180/man3m/signbit.3m.html

I suspect Sun C++ is being strict by not declaring it in <math.h>
because the macro is a C99 feature and the C++ standard incorporates
C89 but not C99 (yet).

In any even, I fixed it by conditionally including <sunmath.h>
on Solaris so we don't lose too many build results overnight:
   http://svn.apache.org/viewvc?rev=646597&view=rev

Martin

> 
> Modified:
>     stdcxx/trunk/src/num_put.cpp
> 
> Modified: stdcxx/trunk/src/num_put.cpp
> URL: http://svn.apache.org/viewvc/stdcxx/trunk/src/num_put.cpp?rev=646396&r1=646395&r2=646396&view=diff
> ==============================================================================
> --- stdcxx/trunk/src/num_put.cpp (original)
> +++ stdcxx/trunk/src/num_put.cpp Wed Apr  9 08:10:18 2008
> @@ -34,6 +34,13 @@
>  #include <stdio.h>    // for snprintf()
>  #include <string.h>   // for memmove(), memset()
>  
> +#include <float.h>   // for _finite(), _fpclass(), _isnan(), _copysign()
> +#include <math.h>    // for isfinite(), isnan(), isinf(), signbit()
> +
> +#ifndef _RWSTD_NO_IEEEFP_H
> +#  include <ieeefp.h>   // for fpclass(), isnan()
> +#endif   // _RWSTD_NO_IEEEFP_H
> +
>  #include <loc/_num_put.h>
>  
>  #include "strtol.h"   // for __rw_digit_map
> @@ -65,6 +72,7 @@
>  #  endif   // _RWSTD_NO_SNPRINTF_IN_LIBC
>  #endif   // _RWSTD_NO_SNPRINTF
>  
> +
>  _RWSTD_NAMESPACE (__rw) { 
>  
>  static const char __rw_digits[] =
> @@ -72,6 +80,155 @@
>      "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
>  
>  
> +#if defined (_MSC_VER)
> +
> +inline bool __rw_isfinite (double val) { return !!_finite (val); }
> +
> +inline bool __rw_signbit (double val) { return 0 > _copysign (1., val); }
> +
> +inline bool __rw_isinf (double val) {
> +    const int fpc = _fpclass (val);
> +
> +    if (_FPCLASS_NINF == fpc) {
> +        // verify that __rw_signbit() correctly determines
> +        // the sign of negative infinity
> +        _RWSTD_ASSERT (__rw_signbit (val));
> +        return true;
> +    }
> +    else if (_FPCLASS_PINF == fpc) {
> +        // verify that __rw_signbit() correctly determines
> +        // the sign of positive infinity
> +        _RWSTD_ASSERT (!__rw_signbit (val));
> +        return true;
> +    }
> +
> +    return false;
> +}
> +
> +inline bool __rw_isnan (double val) { return !!_isnan (val); }
> +
> +inline bool __rw_isqnan (double val) {
> +    return _FPCLASS_QNAN == _fpclass (val);
> +}
> +
> +inline bool __rw_issnan (double val) {
> +    return _FPCLASS_SNAN == _fpclass (val);
> +}
> +
> +#elif defined (_RWSTD_OS_SUNOS)
> +
> +inline bool __rw_isfinite (double val) { return !!finite (val); }
> +
> +inline bool __rw_signbit (double val) { return !!signbit (val); }
> +
> +inline bool __rw_isinf (double val) {
> +    const int fpc = fpclass (val);
> +
> +    if (FP_NINF == fpc) {
> +        // verify that __rw_signbit() correctly determines
> +        // the sign of negative infinity
> +        _RWSTD_ASSERT (__rw_signbit (val));
> +        return true;
> +    }
> +    else if (FP_PINF == fpc) {
> +        // verify that __rw_signbit() correctly determines
> +        // the sign of positive infinity
> +        _RWSTD_ASSERT (!__rw_signbit (val));
> +        return true;
> +    }
> +
> +    return false;
> +}
> +
> +inline bool __rw_isnan (double val) { return 0 != isnan (val); }
> +
> +inline bool __rw_isqnan (double val) { return FP_QNAN == fpclass (val); }
> +
> +inline bool __rw_issnan (double val) { return FP_SNAN == fpclass (val); }
> +
> +#elif defined (fpclassify)
> +
> +inline bool __rw_isfinite (double val) { return !!isfinite (val); }
> +
> +inline bool __rw_signbit (double val) { return !!signbit (val); }
> +
> +inline bool __rw_isinf (double val) { return !!isinf (val); }
> +
> +inline bool __rw_isnan (double val) { return !!isnan (val); }
> +
> +inline bool __rw_isqnan (double val) { return false; }
> +
> +inline bool __rw_issnan (double val) { return false; }
> +
> +#else
> +
> +inline bool __rw_isfinite (double) { return true; }
> +
> +inline bool __rw_signbit (double) { return false; }
> +
> +inline bool __rw_isinf (double) { return false; }
> +
> +inline bool __rw_isnan (double) { return false; }
> +
> +inline bool __rw_isqnan (double) { return false; }
> +
> +inline bool __rw_issnan (double) { return false; }
> +
> +#endif
> +
> +
> +static int
> +__rw_fmat_infinite (char *buf, size_t bufsize, double val, unsigned flags)
> +{
> +    _RWSTD_ASSERT (!__rw_isfinite (val));
> +    _RWSTD_ASSERT (5 <= bufsize);
> +
> +    char* end = buf;
> +    const bool cap = !!(flags & _RWSTD_IOS_UPPERCASE);
> +
> +    if (__rw_isinf (val)) {
> +        if (__rw_signbit (val)) {
> +            *end++ = '-';
> +        }
> +        else if (flags & _RWSTD_IOS_SHOWPOS) {
> +            *end++ = '+';
> +        }
> +
> +        const char str [] = "iInNfF";
> +        *end++ = str [cap + 0];
> +        *end++ = str [cap + 2];
> +        *end++ = str [cap + 4];
> +    }
> +    else {
> +        _RWSTD_ASSERT (__rw_isnan (val));
> +#if 0
> +        // disabled since not all platforms correctly handling sign of NaN's
> +        if (__rw_signbit (val)) {
> +            *end++ = '-';
> +        }
> +        else if (flags & _RWSTD_IOS_SHOWPOS) {
> +            *end++ = '+';
> +        }
> +#endif
> +
> +        const char str [] = "nNaAqQsS";
> +        *end++ = str [cap + 0];
> +        *end++ = str [cap + 2];
> +        *end++ = str [cap + 0];
> +#if 0
> +        // disabled since not all platforms supporting 
> +        // the quiet and signaling NaN's
> +        if (__rw_isqnan (val))
> +            *end++ = str [cap + 4];
> +        else if (__rw_issnan (val))
> +            *end++ = str [cap + 6];
> +#endif
> +    }
> +
> +    return int (end - buf);
> +}
> +
> +
>  #ifdef _RWSTD_LONG_LONG
>  
>  
> @@ -778,88 +935,112 @@
>  
>  #endif   // _RWSTD_LONG_LONG
>  
> -    case __rw_facet::_C_float | __rw_facet::_C_ptr:
> -        fpr = prec < 0 && flags & _RWSTD_IOS_FIXED ? 0 : prec;
> -        fmt = __rw_get_stdio_fmat (fmtbuf, type & ~__rw_facet::_C_ptr,
> -                                   flags, fpr);
> -        for (; ;) {
> -            len = SizeT (_SNPRINTF (*pbuf, bufsize, fmt,
> -                                    *(const float*)pval));
> -
> -            if (len >= bufsize) {
> -                if (*pbuf != buf)
> -                    delete[] *pbuf;
> -
> -                *pbuf = new char [bufsize = len + 1 ? len + 1 : bufsize * 2];
> +    case __rw_facet::_C_float | __rw_facet::_C_ptr: {
> +            const float fval = *(const float*)pval;
> +            if (!__rw_isfinite (fval)) {
> +                len = __rw_fmat_infinite (*pbuf, bufsize, fval, flags);
> +                end = *pbuf + len;
>              }
>              else {
> -                _RWSTD_ASSERT (len > 0);
> -
> -                break;
> -            }
> -        }
> +                fpr = prec < 0 && flags & _RWSTD_IOS_FIXED ? 0 : prec;
> +                fmt = __rw_get_stdio_fmat (fmtbuf, type & ~__rw_facet::_C_ptr,
> +                                           flags, fpr);
> +                for (; ;) {
> +                    len = SizeT (_SNPRINTF (*pbuf, bufsize, fmt, fval));
>  
> -        end = *pbuf + len;
> +                    if (len >= bufsize) {
> +                        if (*pbuf != buf)
> +                            delete[] *pbuf;
>  
> -        // fix up output to conform to C99
> -        __rw_fix_flt (end, len, flags, fpr);
> -        break;
> +                        bufsize = len + 1 ? len + 1 : bufsize * 2;
> +                        *pbuf = new char [bufsize];
> +                    }
> +                    else {
> +                        _RWSTD_ASSERT (len > 0);
>  
> -    case __rw_facet::_C_double | __rw_facet::_C_ptr:
> -        fpr = prec < 0 && flags & _RWSTD_IOS_FIXED ? 0 : prec;
> -        fmt = __rw_get_stdio_fmat (fmtbuf, type & ~__rw_facet::_C_ptr,
> -                                   flags, fpr);
> +                        break;
> +                    }
> +                }
>  
> -        for ( ; ; ) {
> -            len = SizeT (_SNPRINTF (*pbuf, bufsize, fmt,
> -                                    *(const double*)pval));
> +                end = *pbuf + len;
>  
> -            if (len >= bufsize) {
> -                if (*pbuf != buf)
> -                    delete[] *pbuf;
> +                // fix up output to conform to C99
> +                __rw_fix_flt (end, len, flags, fpr);
> +            }
> +        }
> +        break;
>  
> -                *pbuf = new char [bufsize = len + 1 ? len + 1 : bufsize * 2];
> +    case __rw_facet::_C_double | __rw_facet::_C_ptr: {
> +            const double dval = *(const double*)pval;
> +            if (!__rw_isfinite (dval)) {
> +                len = __rw_fmat_infinite (*pbuf, bufsize, dval, flags);
> +                end = *pbuf + len;
>              }
>              else {
> -                _RWSTD_ASSERT (len > 0);
> +                fpr = prec < 0 && flags & _RWSTD_IOS_FIXED ? 0 : prec;
> +                fmt = __rw_get_stdio_fmat (fmtbuf, type & ~__rw_facet::_C_ptr,
> +                                           flags, fpr);
> +
> +                for ( ; ; ) {
> +                    len = SizeT (_SNPRINTF (*pbuf, bufsize, fmt, dval));
> +
> +                    if (len >= bufsize) {
> +                        if (*pbuf != buf)
> +                            delete[] *pbuf;
> +
> +                        bufsize = len + 1 ? len + 1 : bufsize * 2;
> +                        *pbuf = new char [bufsize];
> +                    }
> +                    else {
> +                        _RWSTD_ASSERT (len > 0);
> +
> +                        break;
> +                    }
> +                }
>  
> -                break;
> +                end = *pbuf + len;
> +
> +                // fix up output to conform to C99
> +                __rw_fix_flt (end, len, flags, fpr);
>              }
>          }
> -
> -        end = *pbuf + len;
> -
> -        // fix up output to conform to C99
> -        __rw_fix_flt (end, len, flags, fpr);
>          break;
>  
>  #ifndef _RWSTD_NO_LONG_DOUBLE
>  
> -    case __rw_facet::_C_ldouble | __rw_facet::_C_ptr:
> -        fpr = prec < 0 && flags & _RWSTD_IOS_FIXED ? 0 : prec;
> -        fmt = __rw_get_stdio_fmat (fmtbuf, type & ~__rw_facet::_C_ptr,
> -                                   flags, fpr);
> -
> -        for ( ; ; ) {
> -            len = SizeT (_SNPRINTF (*pbuf, bufsize, fmt,
> -                                    *(const long double*)pval));
> -            if (len >= bufsize) {
> -                if (*pbuf != buf)
> -                    delete[] *pbuf;
> -
> -                *pbuf = new char [bufsize = len + 1 ? len + 1 : bufsize * 2];
> +    case __rw_facet::_C_ldouble | __rw_facet::_C_ptr: {
> +            const long double ldval = *(const long double*)pval;
> +            if (!__rw_isfinite (ldval)) {
> +                len = __rw_fmat_infinite (*pbuf, bufsize, ldval, flags);
> +                end = *pbuf + len;
>              }
>              else {
> -                _RWSTD_ASSERT (len > 0);
> +                fpr = prec < 0 && flags & _RWSTD_IOS_FIXED ? 0 : prec;
> +                fmt = __rw_get_stdio_fmat (fmtbuf, type & ~__rw_facet::_C_ptr,
> +                                           flags, fpr);
> +
> +                for ( ; ; ) {
> +                    len = SizeT (_SNPRINTF (*pbuf, bufsize, fmt, ldval));
> +                    if (len >= bufsize) {
> +                        if (*pbuf != buf)
> +                            delete[] *pbuf;
> +
> +                        bufsize = len + 1 ? len + 1 : bufsize * 2;
> +                        *pbuf = new char [bufsize];
> +                    }
> +                    else {
> +                        _RWSTD_ASSERT (len > 0);
> +
> +                        break;
> +                    }
> +                }
>  
> -                break;
> +                end = *pbuf + len;
> +
> +                // fix up output to conform to C99
> +                __rw_fix_flt (end, len, flags, fpr);
>              }
>          }
> -
> -        end = *pbuf + len;
> -
> -        // fix up output to conform to C99
> -        __rw_fix_flt (end, len, flags, fpr);
>          break;
>  
>  #endif   // _RWSTD_NO_LONG_DOUBLE
> 
> 


Mime
View raw message