summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTorsten Paul <Torsten.Paul@gmx.de>2014-01-23 20:19:15 (GMT)
committerTorsten Paul <Torsten.Paul@gmx.de>2014-01-24 19:52:04 (GMT)
commit1212e2ba7c4d3b3ea20ecf91f716b18f3d1109e0 (patch)
tree5b8ede31e5c38971db44c8796aacecaefe55afff
parent9d55e33b36d8b7fa802ebf6e962375828b05913d (diff)
Handle NaN / +Inf / -Inf in range evaluation (fixes #606).
-rw-r--r--src/value.cc10
-rw-r--r--testdata/scad/features/for-tests.scad36
-rw-r--r--tests/CMakeLists.txt1
-rw-r--r--tests/regression/dumptest/for-tests-expected.csg32
-rw-r--r--tests/regression/echotest/for-tests-expected.echo27
5 files changed, 105 insertions, 1 deletions
diff --git a/src/value.cc b/src/value.cc
index c8a88c6..3a6540f 100644
--- a/src/value.cc
+++ b/src/value.cc
@@ -39,6 +39,10 @@
/*Unicode support for string lengths and array accesses*/
#include <glib.h>
+#include <boost/math/special_functions/fpclassify.hpp>
+using boost::math::isnan;
+using boost::math::isinf;
+
std::ostream &operator<<(std::ostream &stream, const Filename &filename)
{
fs::path fnpath = fs::path( (std::string)filename );
@@ -642,7 +646,11 @@ void Value::RangeType::normalize() {
}
uint32_t Value::RangeType::nbsteps() const {
- if (begin_val == end_val) {
+ if (isnan(step_val) || isinf(begin_val) || (isinf(end_val))) {
+ return std::numeric_limits<uint32_t>::max();
+ }
+
+ if ((begin_val == end_val) || isinf(step_val)) {
return 0;
}
diff --git a/testdata/scad/features/for-tests.scad b/testdata/scad/features/for-tests.scad
index 10295b1..6bb7f69 100644
--- a/testdata/scad/features/for-tests.scad
+++ b/testdata/scad/features/for-tests.scad
@@ -39,3 +39,39 @@ for(r=[1:true:5]) translate([r*10-60,50,0]) cylinder(r=r);
// Vector
for(r=[1,2,5]) translate([r*10-30,0,0]) cylinder(r=r);
+
+nan = 0/0;
+inf = 1/0;
+ninf = -1/0;
+
+echo(nan);
+echo(inf);
+echo(ninf);
+
+// validate step values
+for(i=[0:nan:0]) { echo("NAN", i); }
+for(i=[0:inf:0]) { echo("INF", i); }
+for(i=[0:ninf:0]) { echo("-INF", i); }
+
+for(i=[0:nan:1]) { echo("NAN", i); }
+for(i=[0:inf:1]) { echo("INF", i); }
+for(i=[0:ninf:1]) { echo("-INF", i); }
+
+for(i=[1:nan:0]) { echo("NAN", i); }
+for(i=[1:inf:0]) { echo("INF", i); }
+for(i=[1:ninf:0]) { echo("-INF", i); }
+
+// validate begin / end values
+for(i = [0:inf]) {}
+for(i = [0:ninf]) {}
+for(i = [inf:0]) {}
+for(i = [ninf:0]) {}
+
+for(i = [0:2:inf]) {}
+for(i = [0:2:ninf]) {}
+for(i = [inf:2:0]) {}
+for(i = [ninf:2:0]) {}
+for(i = [inf:2:inf]) {}
+for(i = [ninf:2:ninf]) {}
+for(i = [inf:2:ninf]) {}
+for(i = [ninf:2:inf]) {}
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 053dbf9..e9f2b74 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -804,6 +804,7 @@ file(GLOB FUNCTION_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/functions/*.scad)
file(GLOB EXAMPLE_FILES ${CMAKE_SOURCE_DIR}/../examples/*.scad)
list(APPEND ECHO_FILES ${FUNCTION_FILES}
+ ${CMAKE_SOURCE_DIR}/../testdata/scad/features/for-tests.scad
${CMAKE_SOURCE_DIR}/../testdata/scad/misc/echo-tests.scad
${CMAKE_SOURCE_DIR}/../testdata/scad/misc/escape-test.scad
${CMAKE_SOURCE_DIR}/../testdata/scad/misc/parser-tests.scad
diff --git a/tests/regression/dumptest/for-tests-expected.csg b/tests/regression/dumptest/for-tests-expected.csg
index b61d9cd..4f79afc 100644
--- a/tests/regression/dumptest/for-tests-expected.csg
+++ b/tests/regression/dumptest/for-tests-expected.csg
@@ -128,4 +128,36 @@ group() {
cylinder($fn = 0, $fa = 12, $fs = 2, h = 1, r1 = 5, r2 = 5, center = false);
}
}
+ group();
+ group();
+ group();
+ group();
+ group() {
+ group();
+ }
+ group() {
+ group();
+ }
+ group();
+ group() {
+ group();
+ }
+ group();
+ group();
+ group();
+ group() {
+ group();
+ }
+ group();
+ group();
+ group();
+ group();
+ group();
+ group();
+ group();
+ group();
+ group();
+ group();
+ group();
+ group();
}
diff --git a/tests/regression/echotest/for-tests-expected.echo b/tests/regression/echotest/for-tests-expected.echo
new file mode 100644
index 0000000..7820a41
--- /dev/null
+++ b/tests/regression/echotest/for-tests-expected.echo
@@ -0,0 +1,27 @@
+DEPRECATED: Using ranges of the form [begin:end] with begin value greater than the end value is deprecated.
+DEPRECATED: Using ranges of the form [begin:end] with begin value greater than the end value is deprecated.
+WARNING: Bad range parameter in for statement: too many elements (4294967295).
+ECHO: nan
+ECHO: inf
+ECHO: -inf
+WARNING: Bad range parameter in for statement: too many elements (4294967295).
+ECHO: "INF", 0
+ECHO: "-INF", 0
+WARNING: Bad range parameter in for statement: too many elements (4294967295).
+ECHO: "INF", 0
+WARNING: Bad range parameter in for statement: too many elements (4294967295).
+ECHO: "-INF", 1
+WARNING: Bad range parameter in for statement: too many elements (4294967295).
+DEPRECATED: Using ranges of the form [begin:end] with begin value greater than the end value is deprecated.
+WARNING: Bad range parameter in for statement: too many elements (4294967295).
+DEPRECATED: Using ranges of the form [begin:end] with begin value greater than the end value is deprecated.
+WARNING: Bad range parameter in for statement: too many elements (4294967295).
+WARNING: Bad range parameter in for statement: too many elements (4294967295).
+WARNING: Bad range parameter in for statement: too many elements (4294967295).
+WARNING: Bad range parameter in for statement: too many elements (4294967295).
+WARNING: Bad range parameter in for statement: too many elements (4294967295).
+WARNING: Bad range parameter in for statement: too many elements (4294967295).
+WARNING: Bad range parameter in for statement: too many elements (4294967295).
+WARNING: Bad range parameter in for statement: too many elements (4294967295).
+WARNING: Bad range parameter in for statement: too many elements (4294967295).
+WARNING: Bad range parameter in for statement: too many elements (4294967295).
contact: Jan Huwald // Impressum