diff --git a/src/builtin.c b/src/builtin.c index 6596737f25..bb7895d1e4 100644 --- a/src/builtin.c +++ b/src/builtin.c @@ -216,13 +216,32 @@ static jv f_ ## name(jq_state *jq, jv input, jv a, jv b, jv c) { \ return ret_error2(input, a, error); \ } +#define LIBM_DA(name, type) \ +static jv f_ ## name(jq_state *jq, jv input) { \ + if (jv_get_kind(input) != JV_KIND_NUMBER) { \ + return type_error(input, "number required"); \ + } \ + type value; \ + double d = name(jv_number_value(input), &value); \ + jv ret = JV_ARRAY(jv_number(d), jv_number(value)); \ + jv_free(input); \ + return ret; \ +} +#define LIBM_DA_NO(name, type) \ +static jv f_ ## name(jq_state *jq, jv input) { \ + jv error = jv_string("Error: " #name "/0 not found at build time"); \ + return ret_error(input, error); \ +} + #include "libm.h" #undef LIBM_DDDD_NO #undef LIBM_DDD_NO #undef LIBM_DD_NO +#undef LIBM_DA_NO #undef LIBM_DDDD #undef LIBM_DDD #undef LIBM_DD +#undef LIBM_DA #ifdef __APPLE__ #undef gamma @@ -231,56 +250,6 @@ static jv f_ ## name(jq_state *jq, jv input, jv a, jv b, jv c) { \ #undef exp10 #endif -#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; -} -#else -static jv f_frexp(jq_state *jq, jv input) { - jv error = jv_string("Error: frexp/0 not found at build time"); - return ret_error(input, error); -} -#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)); -} -#else -static jv f_modf(jq_state *jq, jv input) { - jv error = jv_string("Error: modf/0 not found at build time"); - return ret_error(input, error); -} -#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)); -} -#else -static jv f_lgamma_r(jq_state *jq, jv input) { - jv error = jv_string("Error: lgamma_r/0 not found at build time"); - return ret_error(input, error); -} -#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"); @@ -1702,8 +1671,10 @@ static jv f_current_line(jq_state *jq, jv a) { } #define LIBM_DD(name) \ - {f_ ## name, #name, 1}, + {f_ ## name, #name, 1}, #define LIBM_DD_NO(name) LIBM_DD(name) +#define LIBM_DA(name, type) LIBM_DD(name) +#define LIBM_DA_NO(name, type) LIBM_DD(name) #define LIBM_DDD(name) \ {f_ ## name, #name, 3}, @@ -1780,9 +1751,11 @@ BINOPS #undef LIBM_DDDD_NO #undef LIBM_DDD_NO #undef LIBM_DD_NO +#undef LIBM_DA_NO #undef LIBM_DDDD #undef LIBM_DDD #undef LIBM_DD +#undef LIBM_DA struct bytecoded_builtin { const char* name; block code; }; static block bind_bytecoded_builtins(block b) { diff --git a/src/libm.h b/src/libm.h index 8efc1c5e66..00c76e8cc5 100644 --- a/src/libm.h +++ b/src/libm.h @@ -289,3 +289,18 @@ LIBM_DDD(ldexp) #else LIBM_DDD_NO(ldexp) #endif +#ifdef HAVE_MODF +LIBM_DA(modf, double) +#else +LIBM_DA_NO(modf, double) +#endif +#ifdef HAVE_FREXP +LIBM_DA(frexp, int) +#else +LIBM_DA_NO(frex, int) +#endif +#ifdef HAVE_LGAMMA_R +LIBM_DA(lgamma_r, int) +#else +LIBM_DA_NO(lgamma_r, int) +#endif