[EMAIL PROTECTED] 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  <[EMAIL PROTECTED]>

        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



Reply via email to