summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicolas Williams <nico@cryptonector.com>2017-02-04 00:11:19 -0600
committerNicolas Williams <nico@cryptonector.com>2017-02-04 00:11:46 -0600
commit597c1f6667746058e88a9f6fb0415f80fe114b18 (patch)
tree792f708518818caedf0a6021949b145612472544
parent125071cf005e687d4beba9d5822b1c6a72d7d14c (diff)
Add more missing math functions
-rw-r--r--configure.ac37
-rw-r--r--docs/content/3.manual/manual.yml19
-rw-r--r--jq.1.prebuilt16
-rw-r--r--src/builtin.c29
-rw-r--r--src/libm.h150
5 files changed, 244 insertions, 7 deletions
diff --git a/configure.ac b/configure.ac
index 4f640822..59432fdd 100644
--- a/configure.ac
+++ b/configure.ac
@@ -179,29 +179,59 @@ AC_CHECK_MATH_FUNC(acos, [.5])
AC_CHECK_MATH_FUNC(acosh, [.5])
AC_CHECK_MATH_FUNC(asin, [.5])
AC_CHECK_MATH_FUNC(asinh, [.5])
-AC_CHECK_MATH_FUNC(atan, [.5])
AC_CHECK_MATH_FUNC(atan2, [.5,.5])
+AC_CHECK_MATH_FUNC(atan, [.5])
AC_CHECK_MATH_FUNC(atanh, [.5])
AC_CHECK_MATH_FUNC(cbrt, [.5])
+AC_CHECK_MATH_FUNC(ceil,[.5])
+AC_CHECK_MATH_FUNC(copysign,[.5,1.0])
AC_CHECK_MATH_FUNC(cos, [.5])
AC_CHECK_MATH_FUNC(cosh, [.5])
-AC_CHECK_MATH_FUNC(exp, [.5])
+AC_CHECK_MATH_FUNC(drem,[.5,1.0])
+AC_CHECK_MATH_FUNC(erf,[.5])
+AC_CHECK_MATH_FUNC(erfc,[.5])
+AC_CHECK_MATH_FUNC(exp10,[.5])
AC_CHECK_MATH_FUNC(exp2, [.5])
+AC_CHECK_MATH_FUNC(exp, [.5])
+AC_CHECK_MATH_FUNC(expm1,[.5])
+AC_CHECK_MATH_FUNC(fabs,[.5])
+AC_CHECK_MATH_FUNC(fdim,[.5,1.0])
AC_CHECK_MATH_FUNC(floor, [.5])
+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_CHECK_MATH_FUNC(gamma,[.5])
AC_CHECK_MATH_FUNC(hypot, [.5,.5])
AC_CHECK_MATH_FUNC(j0, [.5])
AC_CHECK_MATH_FUNC(j1, [.5])
-AC_CHECK_MATH_FUNC(log, [.5])
+AC_CHECK_MATH_FUNC(ldexp,[.5,2])
+AC_CHECK_MATH_FUNC(lgamma,[.5])
AC_CHECK_MATH_FUNC(log10, [.5])
+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_CHECK_MATH_FUNC(nearbyint,[.5])
+AC_CHECK_MATH_FUNC(nextafter,[.5,1.0])
+AC_CHECK_MATH_FUNC(nexttoward,[.5,1.0])
+AC_CHECK_MATH_FUNC(pow10,[.5])
AC_CHECK_MATH_FUNC(pow, [2,2])
AC_CHECK_MATH_FUNC(remainder, [3,2])
+AC_CHECK_MATH_FUNC(rint,[.5])
+AC_CHECK_MATH_FUNC(round,[.5])
+AC_CHECK_MATH_FUNC(scalb,[.5,1.0])
+AC_CHECK_MATH_FUNC(scalbln,[.5,2])
+AC_CHECK_MATH_FUNC(significand,[.5])
AC_CHECK_MATH_FUNC(sin, [.5])
AC_CHECK_MATH_FUNC(sinh, [.5])
AC_CHECK_MATH_FUNC(sqrt, [.5])
AC_CHECK_MATH_FUNC(tan, [.5])
AC_CHECK_MATH_FUNC(tanh, [.5])
AC_CHECK_MATH_FUNC(tgamma, [.5])
+AC_CHECK_MATH_FUNC(trunc,[.5])
AC_CHECK_MATH_FUNC(y0, [.5])
AC_CHECK_MATH_FUNC(y1, [.5])
@@ -230,4 +260,3 @@ AC_CONFIG_MACRO_DIR([config/m4])
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
-
diff --git a/docs/content/3.manual/manual.yml b/docs/content/3.manual/manual.yml
index c6cffcb0..baad2ad3 100644
--- a/docs/content/3.manual/manual.yml
+++ b/docs/content/3.manual/manual.yml
@@ -2669,13 +2669,30 @@ sections:
that take a single input argument (e.g., `sin()`) are available as
zero-argument jq functions. C math functions that take two input
arguments (e.g., `pow()`) are available as two-argument jq
- functions that ignore `.`.
+ functions that ignore `.`. C math functions that take three input
+ arguments are available as three-argument jq functions that ignore
+ `.`.
Availability of standard math functions depends on the
availability of the corresponding math functions in your operating
system and C math library. Unavailable math functions will be
defined but will raise an error.
+ One-input C math functions: `acos` `acosh` `asin` `asinh` `atan`
+ `atanh` `cbrt` `ceil` `cos` `cosh` `erf` `erfc` `exp` `exp10`
+ `exp2` `expm1` `fabs` `floor` `gamma` `j0` `j1` `lgamma` `log`
+ `log10` `log1p` `log2` `logb` `nearbyint` `pow10` `rint` `round`
+ `significand` `sin` `sinh` `sqrt` `tan` `tanh` `tgamma` `trunc`
+ `y0` `y1`.
+
+ Two-input C math functions: `atan2` `copysign` `drem` `fdim`
+ `fmax` `fmin` `fmod` `frexp` `hypot` `jn` `ldexp` `modf`
+ `nextafter` `nexttoward` `pow` `remainder` `scalb` `scalbln` `yn`.
+
+ Three-input C math functions: `fma`.
+
+ See your system's manual for more information on each of these.
+
- title: 'I/O'
body: |
diff --git a/jq.1.prebuilt b/jq.1.prebuilt
index 2902339e..81c904b5 100644
--- a/jq.1.prebuilt
+++ b/jq.1.prebuilt
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "JQ" "1" "January 2017" "" ""
+.TH "JQ" "1" "February 2017" "" ""
.
.SH "NAME"
\fBjq\fR \- Command\-line JSON processor
@@ -2934,11 +2934,23 @@ jq \'def while(cond; update): def _while: if cond then \., (update | _while) els
jq currently only has IEEE754 double\-precision (64\-bit) floating point number support\.
.
.P
-Besides simple arithmetic operators such as \fB+\fR, jq also has most standard math functions from the C math library\. C math functions that take a single input argument (e\.g\., \fBsin()\fR) are available as zero\-argument jq functions\. C math functions that take two input arguments (e\.g\., \fBpow()\fR) are available as two\-argument jq functions that ignore \fB\.\fR\.
+Besides simple arithmetic operators such as \fB+\fR, jq also has most standard math functions from the C math library\. C math functions that take a single input argument (e\.g\., \fBsin()\fR) are available as zero\-argument jq functions\. C math functions that take two input arguments (e\.g\., \fBpow()\fR) are available as two\-argument jq functions that ignore \fB\.\fR\. C math functions that take three input arguments are available as three\-argument jq functions that ignore \fB\.\fR\.
.
.P
Availability of standard math functions depends on the availability of the corresponding math functions in your operating system and C math library\. Unavailable math functions will be defined but will raise an error\.
.
+.P
+One\-input C math functions: \fBacos\fR \fBacosh\fR \fBasin\fR \fBasinh\fR \fBatan\fR \fBatanh\fR \fBcbrt\fR \fBceil\fR \fBcos\fR \fBcosh\fR \fBerf\fR \fBerfc\fR \fBexp\fR \fBexp10\fR \fBexp2\fR \fBexpm1\fR \fBfabs\fR \fBfloor\fR \fBgamma\fR \fBj0\fR \fBj1\fR \fBlgamma\fR \fBlog\fR \fBlog10\fR \fBlog1p\fR \fBlog2\fR \fBlogb\fR \fBnearbyint\fR \fBpow10\fR \fBrint\fR \fBround\fR \fBsignificand\fR \fBsin\fR \fBsinh\fR \fBsqrt\fR \fBtan\fR \fBtanh\fR \fBtgamma\fR \fBtrunc\fR \fBy0\fR \fBy1\fR\.
+.
+.P
+Two\-input C math functions: \fBatan2\fR \fBcopysign\fR \fBdrem\fR \fBfdim\fR \fBfmax\fR \fBfmin\fR \fBfmod\fR \fBfrexp\fR \fBhypot\fR \fBjn\fR \fBldexp\fR \fBmodf\fR \fBnextafter\fR \fBnexttoward\fR \fBpow\fR \fBremainder\fR \fBscalb\fR \fBscalbln\fR \fByn\fR\.
+.
+.P
+Three\-input C math functions: \fBfma\fR\.
+.
+.P
+See your system\'s manual for more information on each of these\.
+.
.SH "I/O"
At this time jq has minimal support for I/O, mostly in the form of control over when inputs are read\. Two builtins functions are provided for this, \fBinput\fR and \fBinputs\fR, that read from the same sources (e\.g\., \fBstdin\fR, files named on the command\-line) as jq itself\. These two builtins, and jq\'s own reading actions, can be interleaved with each other\.
.
diff --git a/src/builtin.c b/src/builtin.c
index 520d77a2..aa0ab4d5 100644
--- a/src/builtin.c
+++ b/src/builtin.c
@@ -110,9 +110,24 @@ static jv f_ ## name(jq_state *jq, jv input, jv a, jv b) { \
return ret; \
}
#define LIBM_DDD_NO(name)
+
+#define LIBM_DDDD(name) \
+static jv f_ ## name(jq_state *jq, jv input, jv a, jv b, jv c) { \
+ if (jv_get_kind(a) != JV_KIND_NUMBER || jv_get_kind(b) != JV_KIND_NUMBER) \
+ return type_error(input, "number required"); \
+ jv_free(input); \
+ jv ret = jv_number(name(jv_number_value(a), jv_number_value(b), jv_number_value(c))); \
+ jv_free(a); \
+ jv_free(b); \
+ jv_free(c); \
+ return ret; \
+}
+#define LIBM_DDDD_NO(name)
#include "libm.h"
+#undef LIBM_DDDD_NO
#undef LIBM_DDD_NO
#undef LIBM_DD_NO
+#undef LIBM_DDDD
#undef LIBM_DDD
#undef LIBM_DD
@@ -1254,6 +1269,10 @@ static jv f_current_line(jq_state *jq, jv a) {
{(cfunction_ptr)f_ ## name, "_" #name, 3},
#define LIBM_DDD_NO(name)
+#define LIBM_DDDD(name) \
+ {(cfunction_ptr)f_ ## name, "_" #name, 4},
+#define LIBM_DDDD_NO(name)
+
static const struct cfunction function_list[] = {
#include "libm.h"
{(cfunction_ptr)f_plus, "_plus", 3},
@@ -1321,8 +1340,10 @@ static const struct cfunction function_list[] = {
{(cfunction_ptr)f_current_filename, "input_filename", 1},
{(cfunction_ptr)f_current_line, "input_line_number", 1},
};
+#undef LIBM_DDDD_NO
#undef LIBM_DDD_NO
#undef LIBM_DD_NO
+#undef LIBM_DDDD
#undef LIBM_DDD
#undef LIBM_DD
@@ -1375,8 +1396,10 @@ static block bind_bytecoded_builtins(block b) {
#define LIBM_DD(name) "def " #name ": _" #name ";"
#define LIBM_DDD(name) "def " #name "(a;b): _" #name "(a;b);"
+#define LIBM_DDDD(name) "def " #name "(a;b;c): _" #name "(a;b;c);"
#define LIBM_DD_NO(name)
#define LIBM_DDD_NO(name)
+#define LIBM_DDDD_NO(name)
static const char* const jq_builtins =
/* Include supported math functions first */
@@ -1385,19 +1408,25 @@ static const char* const jq_builtins =
#include "src/builtin.inc"
/* Include unsupported math functions next */
+#undef LIBM_DDDD_NO
#undef LIBM_DDD_NO
#undef LIBM_DD_NO
+#undef LIBM_DDDD
#undef LIBM_DDD
#undef LIBM_DD
#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;"
#include "libm.h"
;
+#undef LIBM_DDDD_NO
#undef LIBM_DDD_NO
#undef LIBM_DD_NO
+#undef LIBM_DDDD
#undef LIBM_DDD
#undef LIBM_DD
diff --git a/src/libm.h b/src/libm.h
index 49add490..4b99e1d3 100644
--- a/src/libm.h
+++ b/src/libm.h
@@ -149,3 +149,153 @@ LIBM_DID(jn)
#ifdef HAVE_YN
LIBM_DID(yn)
#endif
+#ifdef HAVE_CEIL
+LIBM_DD(ceil)
+#else
+LIBM_DD_NO(ceil)
+#endif
+#ifdef HAVE_COPYSIGN
+LIBM_DDD(copysign)
+#else
+LIBM_DDD_NO(copysign)
+#endif
+#ifdef HAVE_DREM
+LIBM_DDD(drem)
+#else
+LIBM_DDD_NO(drem)
+#endif
+#ifdef HAVE_ERF
+LIBM_DD(erf)
+#else
+LIBM_DD_NO(erf)
+#endif
+#ifdef HAVE_ERFC
+LIBM_DD(erfc)
+#else
+LIBM_DD_NO(erfc)
+#endif
+#ifdef HAVE_EXP10
+LIBM_DD(exp10)
+#else
+LIBM_DD_NO(exp10)
+#endif
+#ifdef HAVE_EXPM1
+LIBM_DD(expm1)
+#else
+LIBM_DD_NO(expm1)
+#endif
+#ifdef HAVE_FABS
+LIBM_DD(fabs)
+#else
+LIBM_DD_NO(fabs)
+#endif
+#ifdef HAVE_FDIM
+LIBM_DDD(fdim)
+#else
+LIBM_DDD_NO(fdim)
+#endif
+#ifdef HAVE_FMA
+LIBM_DDDD(fma)
+#else
+LIBM_DDDD_NO(fma)
+#endif
+#ifdef HAVE_FMAX
+LIBM_DDD(fmax)
+#else
+LIBM_DDD_NO(fmax)
+#endif
+#ifdef HAVE_FMIN
+LIBM_DDD(fmin)
+#else
+LIBM_DDD_NO(fmin)
+#endif
+#ifdef HAVE_FMOD
+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
+LIBM_DD_NO(gamma)
+#endif
+#ifdef HAVE_LGAMMA
+LIBM_DD(lgamma)
+#else
+LIBM_DD_NO(lgamma)
+#endif
+#ifdef HAVE_LOG1P
+LIBM_DD(log1p)
+#else
+LIBM_DD_NO(log1p)
+#endif
+#ifdef HAVE_LOGB
+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
+LIBM_DD_NO(nearbyint)
+#endif
+#ifdef HAVE_NEXTAFTER
+LIBM_DDD(nextafter)
+#else
+LIBM_DDD_NO(nextafter)
+#endif
+#ifdef HAVE_NEXTTOWARD
+LIBM_DDD(nexttoward)
+#else
+LIBM_DDD_NO(nexttoward)
+#endif
+#ifdef HAVE_POW10
+LIBM_DD(pow10)
+#else
+LIBM_DD_NO(pow10)
+#endif
+#ifdef HAVE_RINT
+LIBM_DD(rint)
+#else
+LIBM_DD_NO(rint)
+#endif
+#ifdef HAVE_ROUND
+LIBM_DD(round)
+#else
+LIBM_DD_NO(round)
+#endif
+#ifdef HAVE_SCALB
+LIBM_DDD(scalb)
+#else
+LIBM_DDD_NO(scalb)
+#endif
+#ifdef HAVE_SCALBLN
+LIBM_DDD(scalbln)
+#else
+LIBM_DDD_NO(scalbln)
+#endif
+#ifdef HAVE_SIGNIFICAND
+LIBM_DD(significand)
+#else
+LIBM_DD_NO(significand)
+#endif
+#ifdef HAVE_TRUNC
+LIBM_DD(trunc)
+#else
+LIBM_DD_NO(trunc)
+#endif
+#ifdef HAVE_LDEXP
+LIBM_DDD(ldexp)
+#else
+LIBM_DDD_NO(ldexp)
+#endif