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 ], [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 ], [0, 0]) +AC_FIND_FUNC([lgamma_r], [m c], [#include ], [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