Skip to content

Commit b24698a

Browse files
committed
vmod: Add vmod_math
This adds the following functions: - math.approx() implementing a notion of "approximately equal" as per the reference in the documentation and source code - math.strfromd() for REAL string formatting without the limitations of the built-in formatter. The main motivation for adding this function at this point is to make the added test case transparent. - math.constant() to access REAL constants from math.h and float.h like DBL_EPSILON or M_PI. - math.fpclass() to access INT constants from math.h to compare the return value of math.fpclassify() against. - functions for all math.h functions and function-like macros like sqrt(), exp() or log(). This uses a python code generator vmod_math_gen.py to extract most of the definitions from the opengroup specification for all the math.h functions and function-like macros and to generate math.constant() and math.fpclass(). The pecification document vmod_math_spec.html is deliberately checked in and added to the distribution to avoid curl running for a normal build. As with other generated code, the generated files vmod_math.c and vmod_math.vcc are also added to the dist, but not to git in order to update them for developer builds based on potential changes to vmod_math_gen.py, but to not run the generator for builds from a distribution.
1 parent 39a9dae commit b24698a

File tree

11 files changed

+1308
-1
lines changed

11 files changed

+1308
-1
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ cscope.*out
8181
/vmod/vcc_*_if.h
8282
/vmod/vmod_*.rst
8383
/vmod/vmod_vcs_version.txt
84+
/vmod/vmod_math.vcc
85+
/vmod/vmod_math.c
8486

8587
# Man-files and binaries
8688
/man/*.1

doc/sphinx/Makefile.am

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,10 @@ include/vmod_proxy.generated.rst: $(top_builddir)/vmod/vmod_proxy.rst
206206
cp $(top_builddir)/vmod/vmod_proxy.rst $@
207207
BUILT_SOURCES += include/vmod_proxy.generated.rst
208208

209+
include/vmod_math.generated.rst: $(top_builddir)/vmod/vmod_math.rst
210+
cp $(top_builddir)/vmod/vmod_math.rst $@
211+
BUILT_SOURCES += include/vmod_math.generated.rst
212+
209213
EXTRA_DIST += $(BUILT_SOURCES)
210214
CLEANFILES = $(BUILT_SOURCES)
211215

doc/sphinx/reference/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ Bundled VMODs
3737
vmod_cookie.rst
3838
vmod_directors.rst
3939
vmod_h2.rst
40+
vmod_math.rst
4041
vmod_proxy.rst
4142
vmod_purge.rst
4243
vmod_std.rst

doc/sphinx/reference/vmod_math.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
..
2+
Copyright (c) 2019 Varnish Software AS
3+
SPDX-License-Identifier: BSD-2-Clause
4+
See LICENSE file for full text of license
5+
6+
7+
.. include:: ../include/vmod_math.generated.rst

man/Makefile.am

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ dist_man_MANS = \
2727
vmod_blob.3 \
2828
vmod_unix.3 \
2929
vmod_proxy.3 \
30-
vmod_h2.3
30+
vmod_h2.3 \
31+
vmod_math.3
3132

3233
CLEANFILES = $(dist_man_MANS)
3334

@@ -146,4 +147,8 @@ vmod_proxy.3: $(top_builddir)/vmod/vmod_proxy.man.rst
146147
vmod_h2.3: $(top_builddir)/vmod/vmod_h2.man.rst
147148
$(BUILD_MAN) $? $@
148149

150+
vmod_math.3: $(top_builddir)/vmod/vmod_math.man.rst
151+
$(BUILD_MAN) $? $@
152+
153+
149154
.NOPATH: $(dist_man_MANS)

vmod/Makefile.am

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ include $(srcdir)/automake_boilerplate_h2.am
3333
include $(srcdir)/automake_boilerplate_cookie.am
3434
include $(srcdir)/automake_boilerplate_debug.am
3535
include $(srcdir)/automake_boilerplate_directors.am
36+
include $(srcdir)/automake_boilerplate_math.am
3637
include $(srcdir)/automake_boilerplate_proxy.am
3738
include $(srcdir)/automake_boilerplate_purge.am
3839
include $(srcdir)/automake_boilerplate_std.am
@@ -55,3 +56,17 @@ vmod_debug_symbols_regex = 'Vmod_.*_Data'
5556

5657
# not --strict, not installed
5758
vmodtoolargs_debug = --boilerplate --noinst -o vcc_debug_if
59+
60+
### vmod_math specific
61+
# the specs are deliberately checked in to not make the build
62+
# dependend on external connectivity
63+
vmod_math_spec.html:
64+
curl -o $@ https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/math.h.html
65+
66+
vmod_math.c: vmod_math.vcc
67+
68+
vmod_math.vcc: vmod_math_spec.html vmod_math_gen.py
69+
@PYTHON@ $(srcdir)/vmod_math_gen.py $< vmod_math.vcc vmod_math.c
70+
71+
# avoid running curl when building from a dist
72+
dist_noinst_SCRIPTS = vmod_math_gen.py vmod_math_spec.html

vmod/automake_boilerplate_math.am

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
## Generated by vmodtool.py --boilerplate.
2+
3+
vmod_LTLIBRARIES += libvmod_math.la
4+
dist_vcc_DATA += $(srcdir)/vmod_math.vcc
5+
6+
libvmod_math_la_SOURCES = \
7+
vmod_math.c \
8+
vmod_math_util.c
9+
10+
libvmod_math_la_CFLAGS =
11+
12+
vmodtoolargs_math ?= --strict --boilerplate -o vcc_math_if
13+
vmod_math_symbols_regex ?= Vmod_math_Data
14+
15+
libvmod_math_la_LDFLAGS = \
16+
-export-symbols-regex $(vmod_math_symbols_regex) \
17+
$(AM_LDFLAGS) \
18+
$(VMOD_LDFLAGS) \
19+
-rpath $(vmoddir)
20+
21+
nodist_libvmod_math_la_SOURCES = vcc_math_if.c vcc_math_if.h
22+
23+
EXTRA_libvmod_math_la_DEPENDENCIES = $(nodist_libvmod_math_la_SOURCES)
24+
25+
EXTRA_DIST += automake_boilerplate_math.am
26+
27+
$(libvmod_math_la_OBJECTS): vcc_math_if.h
28+
29+
vcc_math_if.h vmod_math.rst vmod_math.man.rst: vcc_math_if.c
30+
31+
# A doc-change will not update mtime on the .h and .c files, so a
32+
# touch(1) is necessary to signal that vmodtool was in fact run.
33+
vcc_math_if.c: $(VMODTOOL) $(srcdir)/vmod_math.vcc
34+
@PYTHON@ $(VMODTOOL) $(vmodtoolargs_math) $(srcdir)/vmod_math.vcc
35+
touch vcc_math_if.c
36+
37+
clean-local: clean-vmod-math
38+
39+
clean-vmod-math:
40+
rm -f $(nodist_libvmod_math_la_SOURCES)
41+
rm -f vmod_math.rst vmod_math.man.rst

vmod/tests/math_b00000.vtc

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
varnishtest vmod_math
2+
3+
varnish v1 -vcl {
4+
import math;
5+
6+
backend proforma none;
7+
8+
sub vcl_recv {
9+
return (synth(200));
10+
}
11+
12+
sub vcl_synth {
13+
# formatting basics
14+
set resp.http."n.v" = 0.1;
15+
set resp.http."n.13a" = math.strfromd("%.13a", 0.1);
16+
set resp.http."n.17e" = math.strfromd("%.17e", 0.1);
17+
set resp.http."n.17f" = math.strfromd("%.17f", 0.1);
18+
set resp.http."n.g" = math.strfromd("%g", 0.1);
19+
20+
# edge cases where approx makes a difference
21+
22+
set resp.http."sinpi.v" = math.sin(math.constant(M_PI));
23+
set resp.http."sinpi.17f" = math.strfromd("%.17f", math.sin(math.constant(M_PI)));
24+
set resp.http."sinpi.0.equals" = math.sin(math.constant(M_PI)) == 0.0;
25+
set resp.http."sinpi.0.approx" = math.approx(math.sin(math.constant(M_PI)), 0);
26+
set resp.http."sinpi.0.zero" =
27+
math.fpclassify(math.sin(math.constant(M_PI))) ==
28+
math.fpclass(FP_ZERO);
29+
30+
# VRT_DECIMAL_MAX == 0x426d1a94a1fffff8
31+
set resp.http."some1.v" = 999999999999 + 0.999;
32+
set resp.http."some1.f" = math.strfromd("%f", 999999999999 + 0.999);
33+
# VRT_DECIMAL_MAX - ULP == 0x426d1a94a1fffff7
34+
set resp.http."some2.v" = 999999999999 + (9.989 / 10);
35+
set resp.http."some2.f" = math.strfromd("%f", 999999999999 + (9.989 / 10));
36+
37+
set resp.http."some1.some2.equals" =
38+
(999999999999 + 0.999) == (999999999999 + (9.989 / 10));
39+
set resp.http."some1.some2.approx" =
40+
math.approx(999999999999 + 0.999, 999999999999 + (9.989 / 10));
41+
42+
return (deliver);
43+
}
44+
} -start
45+
46+
client c1 {
47+
txreq
48+
rxresp
49+
expect resp.status == 200
50+
51+
expect resp.http.n.v == 0.100
52+
expect resp.http.n.13a == 0x1.999999999999ap-4
53+
expect resp.http.n.17e == 1.00000000000000006e-01
54+
expect resp.http.n.17f == 0.10000000000000001
55+
expect resp.http.n.g == 0.1
56+
57+
expect resp.http.sinpi.v == 0.000
58+
expect resp.http.sinpi.17f == 0.00000000000000012
59+
expect resp.http.sinpi.0.equals == false
60+
expect resp.http.sinpi.0.approx == true
61+
expect resp.http.sinpi.0.zero == false
62+
63+
expect resp.http.some1.v == 999999999999.999
64+
expect resp.http.some1.f == 999999999999.999023
65+
expect resp.http.some2.v == 999999999999.999
66+
expect resp.http.some2.f == 999999999999.998901
67+
expect resp.http.some1.some2.equals == false
68+
expect resp.http.some1.some2.approx == true
69+
} -run

0 commit comments

Comments
 (0)