#define PERLIO_NOT_STDIO 1
#include "perl.h"
#include "XSUB.h"
+
+static int not_here(const char *s);
+
#if defined(PERL_IMPLICIT_SYS)
# undef signal
# undef open
#include <float.h>
#endif
#ifdef I_FENV
+#if !(defined(__vax__) && defined(__NetBSD__))
#include <fenv.h>
#endif
+#endif
#ifdef I_LIMITS
#include <limits.h>
#endif
#ifndef c99_fdim
static NV my_fdim(NV x, NV y)
{
+#ifdef NV_NAN
return (Perl_isnan(x) || Perl_isnan(y)) ? NV_NAN : (x > y ? x - y : 0);
+#else
+ return (x > y ? x - y : 0);
+#endif
}
# define c99_fdim my_fdim
#endif
#ifndef c99_fmax
static NV my_fmax(NV x, NV y)
{
+#ifdef NV_NAN
if (Perl_isnan(x)) {
return Perl_isnan(y) ? NV_NAN : y;
} else if (Perl_isnan(y)) {
return x;
}
+#endif
return x > y ? x : y;
}
# define c99_fmax my_fmax
#ifndef c99_fmin
static NV my_fmin(NV x, NV y)
{
+#ifdef NV_NAN
if (Perl_isnan(x)) {
return Perl_isnan(y) ? NV_NAN : y;
} else if (Perl_isnan(y)) {
return x;
}
+#endif
return x < y ? x : y;
}
# define c99_fmin my_fmin
x = PERL_ABS(x); /* Take absolute values. */
if (y == 0)
return x;
+#ifdef NV_INF
if (Perl_isnan(y))
return NV_INF;
+#endif
y = PERL_ABS(y);
if (x < y) { /* Swap so that y is less. */
t = x;
static NV my_tgamma(NV x)
{
const NV gamma = 0.577215664901532860606512090; /* Euler's gamma constant. */
+#ifdef NV_NAN
if (Perl_isnan(x) || x < 0.0)
return NV_NAN;
+#endif
+#ifdef NV_INF
if (x == 0.0 || x == NV_INF)
+#ifdef DOUBLE_IS_IEEE_FORMAT
return x == -0.0 ? -NV_INF : NV_INF;
+#else
+ return NV_INF;
+#endif
+#endif
/* The function domain is split into three intervals:
* (0, 0.001), [0.001, 12), and (12, infinity) */
return result;
}
+#ifdef NV_INF
/* Third interval: [12, +Inf) */
#if LDBL_MANT_DIG == 113 /* IEEE quad prec */
if (x > 1755.548) {
return NV_INF;
}
#endif
+#endif
return Perl_exp(c99_lgamma(x));
}
#ifdef USE_MY_LGAMMA
static NV my_lgamma(NV x)
{
+#ifdef NV_NAN
if (Perl_isnan(x))
return NV_NAN;
+#endif
+#ifdef NV_INF
if (x <= 0 || x == NV_INF)
return NV_INF;
+#endif
if (x == 1.0 || x == 2.0)
return 0;
if (x < 12.0)
{
/* http://www.johndcook.com/cpp_log_one_plus_x.html -- public domain.
* Taylor series, the first four terms (the last term quartic). */
+#ifdef NV_NAN
if (x < -1.0)
return NV_NAN;
+#endif
+#ifdef NV_INF
if (x == -1.0)
return -NV_INF;
+#endif
if (PERL_ABS(x) > 1e-4)
return Perl_log(1.0 + x);
else
case FE_TOWARDZERO: return MY_ROUND_TRUNC(x);
case FE_DOWNWARD: return MY_ROUND_DOWN(x);
case FE_UPWARD: return MY_ROUND_UP(x);
- default: return NV_NAN;
+ default: break;
}
#elif defined(HAS_FPGETROUND)
switch (fpgetround()) {
case FP_RZ: return MY_ROUND_TRUNC(x);
case FP_RM: return MY_ROUND_DOWN(x);
case FE_RP: return MY_ROUND_UP(x);
- default: return NV_NAN;
+ default: break;
}
-#else
- return NV_NAN;
#endif
+ not_here("rint");
}
#endif
# define c99_trunc my_trunc
#endif
+#ifdef NV_NAN
+
#undef NV_PAYLOAD_DEBUG
/* NOTE: the NaN payload API implementation is hand-rolled, since the
# define NV_PAYLOAD_TYPE NV
#endif
-#ifdef LONGDOUBLE_DOUBLEDOUBLE
-# define NV_PAYLOAD_SIZEOF_ASSERT(a) assert(sizeof(a) == NVSIZE / 2)
+#if defined(USE_LONG_DOUBLE) && defined(LONGDOUBLE_DOUBLEDOUBLE)
+# define NV_PAYLOAD_SIZEOF_ASSERT(a) \
+ STATIC_ASSERT_STMT(sizeof(a) == NVSIZE / 2)
#else
-# define NV_PAYLOAD_SIZEOF_ASSERT(a) assert(sizeof(a) == NVSIZE)
+# define NV_PAYLOAD_SIZEOF_ASSERT(a) \
+ STATIC_ASSERT_STMT(sizeof(a) == NVSIZE)
#endif
static void S_setpayload(NV* nvp, NV_PAYLOAD_TYPE payload, bool signaling)
return payload;
}
+#endif /* #ifdef NV_NAN */
+
/* XXX This comment is just to make I_TERMIO and I_SGTTY visible to
metaconfig for future extension writers. We don't use them in POSIX.
(This is really sneaky :-) --AD
SV *const t = newSVrv(rv, packname);
void *const p = sv_grow(t, size + 1);
+ /* Ensure at least one use of not_here() to avoid "defined but not
+ * used" warning. This is not at all related to allocate_struct(); I
+ * just needed somewhere to dump it - DAPM */
+ if (0) { not_here(""); }
+
SvCUR_set(t, size);
SvPOK_on(t);
return p;
(void) hv_store(RETVAL,
strings->name,
strlen(strings->name),
- newSVpvn_utf8(value,
- strlen(value),
-
- /* We mark it as UTF-8 if a utf8 locale
- * and is valid and variant under UTF-8 */
- is_utf8_locale
- && ! is_invariant_string((U8 *) value, 0)
- && is_utf8_string((U8 *) value, 0)),
- 0);
- }
+ newSVpvn_utf8(
+ value,
+ strlen(value),
+
+ /* We mark it as UTF-8 if a utf8 locale and is
+ * valid and variant under UTF-8 */
+ is_utf8_locale
+ && ! is_utf8_invariant_string((U8 *) value, 0)
+ && is_utf8_string((U8 *) value, 0)),
+ 0);
+ }
strings++;
}
y1 = 30
CODE:
PERL_UNUSED_VAR(x);
+#ifdef NV_NAN
RETVAL = NV_NAN;
+#else
+ RETVAL = 0;
+#endif
switch (ix) {
case 0:
RETVAL = Perl_acos(x); /* C89 math */
#ifdef Perl_signbit
RETVAL = Perl_signbit(x);
#else
- RETVAL = (x < 0) || (x == -0.0);
+ RETVAL = (x < 0);
+#ifdef DOUBLE_IS_IEEE_FORMAT
+ if (x == -0.0) {
+ RETVAL = TRUE;
+ }
+#endif
#endif
break;
}
getpayload(nv)
NV nv
CODE:
+#ifdef DOUBLE_HAS_NAN
RETVAL = S_getpayload(nv);
+#else
+ PERL_UNUSED_VAR(nv);
+ not_here("getpayload");
+#endif
OUTPUT:
RETVAL
NV nv
NV payload
CODE:
+#ifdef DOUBLE_HAS_NAN
S_setpayload(&nv, payload, FALSE);
+#else
+ PERL_UNUSED_VAR(nv);
+ PERL_UNUSED_VAR(payload);
+ not_here("setpayload");
+#endif
OUTPUT:
nv
NV nv
NV payload
CODE:
+#ifdef DOUBLE_HAS_NAN
nv = NV_NAN;
S_setpayload(&nv, payload, TRUE);
+#else
+ PERL_UNUSED_VAR(nv);
+ PERL_UNUSED_VAR(payload);
+ not_here("setpayloadsig");
+#endif
OUTPUT:
nv
issignaling(nv)
NV nv
CODE:
+#ifdef DOUBLE_HAS_NAN
RETVAL = Perl_isnan(nv) && NV_NAN_IS_SIGNALING(&nv);
+#else
+ PERL_UNUSED_VAR(nv);
+ not_here("issignaling");
+#endif
OUTPUT:
RETVAL
CODE:
PERL_UNUSED_VAR(x);
PERL_UNUSED_VAR(y);
+#ifdef NV_NAN
RETVAL = NV_NAN;
+#else
+ RETVAL = 0;
+#endif
switch (ix) {
case 0:
#ifdef c99_copysign
}
#elif defined(c99_nan)
{
- STRLEN elen = my_snprintf(PL_efloatbuf, PL_efloatsize, "%g", nv);
+ STRLEN elen = my_snprintf(PL_efloatbuf, PL_efloatsize, "%g", payload);
if ((IV)elen == -1) {
+#ifdef NV_NAN
RETVAL = NV_NAN;
+#else
+ not_here("nan");
+#endif
} else {
RETVAL = c99_nan(PL_efloatbuf);
}
ALIAS:
yn = 1
CODE:
+#ifdef NV_NAN
RETVAL = NV_NAN;
+#else
+ RETVAL = 0;
+#endif
switch (ix) {
case 0:
#ifdef bessel_jn
const char *s = SvPVX_const(ST(0));
int i = whichsig(s);
- if (i < 0 && memEQ(s, "SIG", 3))
+ if (i < 0 && _memEQs(s, "SIG"))
i = whichsig(s + 3);
if (i < 0) {
if (ckWARN(WARN_SIGNAL))
if (result == (time_t)-1)
SvOK_off(TARG);
else if (result == 0)
- sv_setpvn(TARG, "0 but true", 10);
+ sv_setpvs(TARG, "0 but true");
else
sv_setiv(TARG, (IV)result);
} else {
STRLEN len = strlen(buf);
sv_usepvn_flags(sv, buf, len, SV_HAS_TRAILING_NUL);
if (SvUTF8(fmt)
- || (! is_invariant_string((U8*) buf, len)
+ || (! is_utf8_invariant_string((U8*) buf, len)
&& is_utf8_string((U8*) buf, len)
#ifdef USE_LOCALE_TIME
&& _is_cur_LC_category_utf8(LC_TIME)