summaryrefslogtreecommitdiffstats
path: root/src/glsl/s_expression.cpp
diff options
context:
space:
mode:
authorPaul Berry <stereotype441@gmail.com>2012-01-17 10:28:10 -0800
committerPaul Berry <stereotype441@gmail.com>2012-01-19 18:45:22 -0800
commit4f82fed49359676fc19598f8c65ca51958dd2d79 (patch)
tree5914359f9f0c8a396d978cbef2bf76252d3af9ea /src/glsl/s_expression.cpp
parent5e576efef2397e6748e0dc727d92d1064bf90efe (diff)
downloadexternal_mesa3d-4f82fed49359676fc19598f8c65ca51958dd2d79.zip
external_mesa3d-4f82fed49359676fc19598f8c65ca51958dd2d79.tar.gz
external_mesa3d-4f82fed49359676fc19598f8c65ca51958dd2d79.tar.bz2
glsl: Fix isinf() for non-C99-compliant compilers.
Commit ede60bc4670a8d9c14921c77abee1ac57fc0e6bf (glsl: Add isinf() and isnan() builtins) uses "+INF" in the .ir file to represent infinity. This worked on C99-compliant compilers, since the s-expression reader uses strtod() to read numbers, and C99 requires strtod() to understand "+INF". However, it didn't work on non-C99-compliant compilers such as MSVC. This patch modifies the s-expression reader to explicitly check for "+INF" rather than relying on strtod() to support it. This is a candidate for the 8.0 branch. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=44767 Tested-by: Morgan Armand <morgan.devel@gmail.com> Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
Diffstat (limited to 'src/glsl/s_expression.cpp')
-rw-r--r--src/glsl/s_expression.cpp36
1 files changed, 22 insertions, 14 deletions
diff --git a/src/glsl/s_expression.cpp b/src/glsl/s_expression.cpp
index e704a3b..57de9d3 100644
--- a/src/glsl/s_expression.cpp
+++ b/src/glsl/s_expression.cpp
@@ -23,6 +23,7 @@
*/
#include <assert.h>
+#include <limits>
#include "s_expression.h"
s_symbol::s_symbol(const char *str, size_t n)
@@ -64,21 +65,28 @@ read_atom(void *ctx, const char *&src, char *&symbol_buffer)
if (n == 0)
return NULL; // no atom
- // Check if the atom is a number.
- char *float_end = NULL;
- double f = glsl_strtod(src, &float_end);
- if (float_end != src) {
- char *int_end = NULL;
- int i = strtol(src, &int_end, 10);
- // If strtod matched more characters, it must have a decimal part
- if (float_end > int_end)
- expr = new(ctx) s_float(f);
- else
- expr = new(ctx) s_int(i);
+ // Check for the special symbol '+INF', which means +Infinity. Note: C99
+ // requires strtod to parse '+INF' as +Infinity, but we still support some
+ // non-C99-compliant compilers (e.g. MSVC).
+ if (n == 4 && strncmp(src, "+INF", 4) == 0) {
+ expr = new(ctx) s_float(std::numeric_limits<float>::infinity());
} else {
- // Not a number; return a symbol.
- symbol_buffer[n] = '\0';
- expr = new(ctx) s_symbol(symbol_buffer, n);
+ // Check if the atom is a number.
+ char *float_end = NULL;
+ double f = glsl_strtod(src, &float_end);
+ if (float_end != src) {
+ char *int_end = NULL;
+ int i = strtol(src, &int_end, 10);
+ // If strtod matched more characters, it must have a decimal part
+ if (float_end > int_end)
+ expr = new(ctx) s_float(f);
+ else
+ expr = new(ctx) s_int(i);
+ } else {
+ // Not a number; return a symbol.
+ symbol_buffer[n] = '\0';
+ expr = new(ctx) s_symbol(symbol_buffer, n);
+ }
}
src += n;