Because %i sscanf() converters are deprecated, and in practice clamp to [-2^31, 2^31) on 32 bit.
-- v2: tests: Read integer uniforms with strtol() and strtoul().
From: Giovanni Mascellani gmascellani@codeweavers.com
Because %i sscanf() converters are deprecated, and in practice clamp to [-2^31, 2^31) on 32 bit. --- tests/shader_runner.c | 70 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 63 insertions(+), 7 deletions(-)
diff --git a/tests/shader_runner.c b/tests/shader_runner.c index 10c6dd21..09c0dc0c 100644 --- a/tests/shader_runner.c +++ b/tests/shader_runner.c @@ -371,6 +371,58 @@ static void set_uniforms(struct shader_runner *runner, size_t offset, size_t cou memcpy(runner->uniforms + offset, uniforms, count * sizeof(*runner->uniforms)); }
+static void read_int(const char **line, int *ptr) +{ + char *rest; + long val; + + errno = 0; + val = strtol(*line, &rest, 0); + + if (errno != 0) + fatal_error("Malformed int constant '%s'.\n", *line); + + *ptr = val; + if (*ptr != val) + fatal_error("Out of range int constant '%s'.\n", *line); + + *line = rest; +} + +static void read_uint(const char **line, unsigned int *ptr) +{ + char *rest; + unsigned long val; + + errno = 0; + val = strtoul(*line, &rest, 0); + + if (errno != 0) + fatal_error("Malformed uint constant '%s'.\n", *line); + + *ptr = val; + if (*ptr != val) + fatal_error("Out of range uint constant '%s'.\n", *line); + + *line = rest; +} + +static void read_int4(const char **line, int (*v)[4]) +{ + read_int(line, &(*v)[0]); + read_int(line, &(*v)[1]); + read_int(line, &(*v)[2]); + read_int(line, &(*v)[3]); +} + +static void read_uint4(const char **line, unsigned int (*v)[4]) +{ + read_uint(line, &(*v)[0]); + read_uint(line, &(*v)[1]); + read_uint(line, &(*v)[2]); + read_uint(line, &(*v)[3]); +} + static void parse_test_directive(struct shader_runner *runner, const char *line) { char *rest; @@ -590,28 +642,32 @@ static void parse_test_directive(struct shader_runner *runner, const char *line) fatal_error("Malformed float constant '%s'.\n", line); set_uniforms(runner, offset, 1, &f); } - else if (match_string(line, "int4", &line) || match_string(line, "uint4", &line)) + else if (match_string(line, "int4", &line)) { int v[4];
- if (sscanf(line, "%i %i %i %i", &v[0], &v[1], &v[2], &v[3]) < 4) - fatal_error("Malformed (u)int4 constant '%s'.\n", line); + read_int4(&line, &v); + set_uniforms(runner, offset, 4, v); + } + else if (match_string(line, "uint4", &line)) + { + unsigned int v[4]; + + read_uint4(&line, &v); set_uniforms(runner, offset, 4, v); } else if (match_string(line, "int", &line)) { int i;
- if (sscanf(line, "%i", &i) < 1) - fatal_error("Malformed int constant '%s'.\n", line); + read_int(&line, &i); set_uniforms(runner, offset, 1, &i); } else if (match_string(line, "uint", &line)) { unsigned int u;
- if (sscanf(line, "%u", &u) < 1) - fatal_error("Malformed uint constant '%s'.\n", line); + read_uint(&line, &u); set_uniforms(runner, offset, 1, &u); } else
+static void read_int(const char **line, int *ptr)
I think "ptr" is a bit of an awkward name for this. Likewise for read_uint().
+static void read_int4(const char **line, int (*v)[4])
The "natural" type for "v" would seem struct ivec4. I imagine the choice of passing an array was largely dictated by the set_uniforms() interface, but perhaps it shouldn't be? Likewise for read_uint4().