summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicolas Williams <nico@cryptonector.com>2017-03-29 00:07:42 -0500
committerNicolas Williams <nico@cryptonector.com>2017-03-29 00:07:42 -0500
commit71d4ff6ed8c35489a644fc8c8eb565f8d4408693 (patch)
tree111a5c2a86fdfa9bce90329cbe82002c56438c87
parent7935d307f06133287c381110d1bcd4ac39aa9080 (diff)
Fix frexp, modf, lgamma_r (fix #1374)
-rw-r--r--configure.ac5
-rw-r--r--src/builtin.c59
-rw-r--r--src/libm.h10
3 files changed, 59 insertions, 15 deletions
diff --git a/configure.ac b/configure.ac
index 1c776925..3d7d8b29 100644
--- a/configure.ac
+++ b/configure.ac
@@ -174,7 +174,7 @@ AC_CHECK_MATH_FUNC(fma,[.5,1.0,1.5])
AC_CHECK_MATH_FUNC(fmax,[.5,1.0])
AC_CHECK_MATH_FUNC(fmin,[.5,1.0])
AC_CHECK_MATH_FUNC(fmod,[.5,1.0])
-AC_CHECK_MATH_FUNC(frexp,[.5,1.0])
+AC_FIND_FUNC([frexp], [m c], [#include <math.h>], [0, 0])
AC_CHECK_MATH_FUNC(gamma,[.5])
AC_CHECK_MATH_FUNC(hypot, [.5,.5])
AC_CHECK_MATH_FUNC(j0, [.5])
@@ -186,7 +186,8 @@ AC_CHECK_MATH_FUNC(log1p,[.5])
AC_CHECK_MATH_FUNC(log2, [.5])
AC_CHECK_MATH_FUNC(log, [.5])
AC_CHECK_MATH_FUNC(logb,[.5])
-AC_CHECK_MATH_FUNC(modf,[.5,1.0])
+AC_FIND_FUNC([modf], [m c], [#include <math.h>], [0, 0])
+AC_FIND_FUNC([lgamma_r], [m c], [#include <math.h>], [0, 0])
AC_CHECK_MATH_FUNC(nearbyint,[.5])
AC_CHECK_MATH_FUNC(nextafter,[.5,1.0])
AC_CHECK_MATH_FUNC(nexttoward,[.5,1.0])
diff --git a/src/builtin.c b/src/builtin.c
index 578c4417..2973c4fd 100644
--- a/src/builtin.c
+++ b/src/builtin.c
@@ -150,6 +150,41 @@ static jv f_ ## name(jq_state *jq, jv input, jv a, jv b, jv c) { \
#undef LIBM_DDD
#undef LIBM_DD
+#ifdef HAVE_FREXP
+static jv f_frexp(jq_state *jq, jv input) {
+ if (jv_get_kind(input) != JV_KIND_NUMBER) {
+ return type_error(input, "number required");
+ }
+ int exp;
+ double d = frexp(jv_number_value(input), &exp);
+ jv ret = JV_ARRAY(jv_number(d), jv_number(exp));
+ jv_free(input);
+ return ret;
+}
+#endif
+#ifdef HAVE_MODF
+static jv f_modf(jq_state *jq, jv input) {
+ if (jv_get_kind(input) != JV_KIND_NUMBER) {
+ return type_error(input, "number required");
+ }
+ double i;
+ jv ret = JV_ARRAY(jv_number(modf(jv_number_value(input), &i)));
+ jv_free(input);
+ return jv_array_append(ret, jv_number(i));
+}
+#endif
+#ifdef HAVE_LGAMMA_R
+static jv f_lgamma_r(jq_state *jq, jv input) {
+ if (jv_get_kind(input) != JV_KIND_NUMBER) {
+ return type_error(input, "number required");
+ }
+ int sign;
+ jv ret = JV_ARRAY(jv_number(lgamma_r(jv_number_value(input), &sign)));
+ jv_free(input);
+ return jv_array_append(ret, jv_number(sign));
+}
+#endif
+
static jv f_negate(jq_state *jq, jv input) {
if (jv_get_kind(input) != JV_KIND_NUMBER) {
return type_error(input, "cannot be negated");
@@ -1434,6 +1469,15 @@ static jv f_current_line(jq_state *jq, jv a) {
static const struct cfunction function_list[] = {
#include "libm.h"
+#ifdef HAVE_FREXP
+ {(cfunction_ptr)f_frexp,"frexp", 1},
+#endif
+#ifdef HAVE_MODF
+ {(cfunction_ptr)f_modf,"modf", 1},
+#endif
+#ifdef HAVE_LGAMMA_R
+ {(cfunction_ptr)f_lgamma_r,"lgamma_r", 1},
+#endif
{(cfunction_ptr)f_plus, "_plus", 3},
{(cfunction_ptr)f_negate, "_negate", 1},
{(cfunction_ptr)f_minus, "_minus", 3},
@@ -1566,10 +1610,19 @@ static const char* const jq_builtins =
#define LIBM_DD(name)
#define LIBM_DDD(name)
#define LIBM_DDDD(name)
-#define LIBM_DD_NO(name) "def " #name ": \"Error: " #name "() not found at build time\"|error;"
-#define LIBM_DDD_NO(name) "def " #name "(a;b): \"Error: " #name "() not found at build time\"|error;"
-#define LIBM_DDDD_NO(name) "def " #name "(a;b;c): \"Error: " #name "() not found at build time\"|error;"
+#define LIBM_DD_NO(name) "def " #name ": \"Error: " #name "/0 not found at build time\"|error;"
+#define LIBM_DDD_NO(name) "def " #name "(a;b): \"Error: " #name "/2 not found at build time\"|error;"
+#define LIBM_DDDD_NO(name) "def " #name "(a;b;c): \"Error: " #name "/3 not found at build time\"|error;"
#include "libm.h"
+#ifndef HAVE_FREXP
+ "def frexp: \"Error: frexp/0 not found found at build time\"|error;"
+#endif
+#ifndef HAVE_MODF
+ "def modf: \"Error: modf/0 not found found at build time\"|error;"
+#endif
+#ifndef HAVE_LGAMMA_R
+ "def lgamma_r: \"Error: lgamma_r/0 not found found at build time\"|error;"
+#endif
;
#undef LIBM_DDDD_NO
diff --git a/src/libm.h b/src/libm.h
index 81f6efd1..fe2bb79e 100644
--- a/src/libm.h
+++ b/src/libm.h
@@ -214,11 +214,6 @@ LIBM_DDD(fmod)
#else
LIBM_DDD_NO(fmod)
#endif
-#ifdef HAVE_FREXP
-LIBM_DDD(frexp)
-#else
-LIBM_DDD_NO(frexp)
-#endif
#ifdef HAVE_GAMMA
LIBM_DD(gamma)
#else
@@ -239,11 +234,6 @@ LIBM_DD(logb)
#else
LIBM_DD_NO(logb)
#endif
-#ifdef HAVE_MODF
-LIBM_DDD(modf)
-#else
-LIBM_DDD_NO(modf)
-#endif
#ifdef HAVE_NEARBYINT
LIBM_DD(nearbyint)
#else