summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKenneth Graunke <kenneth@whitecape.org>2010-08-18 18:03:22 -0700
committerKenneth Graunke <kenneth@whitecape.org>2010-08-18 21:33:18 -0700
commit365ce61997a28a0c0dad79e7d3f7616e57f105f5 (patch)
tree78305e51c626e153393a999261d44077ef0feb87
parenta575067d7029c7af3bb6d650d6bd944ac8bb6bb7 (diff)
glsl: Replace sscanf in s_expression reader with strspn and strcspn.
This seems to give roughly a 20% speedup.
-rw-r--r--src/glsl/s_expression.cpp49
-rw-r--r--src/glsl/s_expression.h2
2 files changed, 30 insertions, 21 deletions
diff --git a/src/glsl/s_expression.cpp b/src/glsl/s_expression.cpp
index 26be23ea8fa..4458c48d6ba 100644
--- a/src/glsl/s_expression.cpp
+++ b/src/glsl/s_expression.cpp
@@ -28,9 +28,9 @@
#include <assert.h>
#include "s_expression.h"
-s_symbol::s_symbol(const char *tmp)
+s_symbol::s_symbol(const char *tmp, size_t n)
{
- this->str = talloc_strdup (this, tmp);
+ this->str = talloc_strndup (this, tmp, n);
assert(this->str != NULL);
}
@@ -51,26 +51,34 @@ s_list::length() const
static s_expression *
read_atom(void *ctx, const char *& src)
{
- char buf[101];
- int n;
- if (sscanf(src, " %100[^( \v\t\r\n)]%n", buf, &n) != 1)
+ s_expression *expr = NULL;
+
+ // Skip leading spaces.
+ src += strspn(src, " \v\t\r\n");
+
+ size_t n = strcspn(src, "( \v\t\r\n)");
+ if (n == 0)
return NULL; // no atom
- src += n;
// Check if the atom is a number.
char *float_end = NULL;
- double f = strtod(buf, &float_end);
- if (float_end != buf) {
+ double f = strtod(src, &float_end);
+ if (float_end != src) {
char *int_end = NULL;
- int i = strtol(buf, &int_end, 10);
+ int i = strtol(src, &int_end, 10);
// If strtod matched more characters, it must have a decimal part
if (float_end > int_end)
- return new(ctx) s_float(f);
-
- return new(ctx) s_int(i);
+ expr = new(ctx) s_float(f);
+ else
+ expr = new(ctx) s_int(i);
+ } else {
+ // Not a number; return a symbol.
+ expr = new(ctx) s_symbol(src, n);
}
- // Not a number; return a symbol.
- return new(ctx) s_symbol(buf);
+
+ src += n;
+
+ return expr;
}
s_expression *
@@ -82,10 +90,10 @@ s_expression::read_expression(void *ctx, const char *&src)
if (atom != NULL)
return atom;
- char c;
- int n;
- if (sscanf(src, " %c%n", &c, &n) == 1 && c == '(') {
- src += n;
+ // Skip leading spaces.
+ src += strspn(src, " \v\t\r\n");
+ if (src[0] == '(') {
+ ++src;
s_list *list = new(ctx) s_list;
s_expression *expr;
@@ -93,11 +101,12 @@ s_expression::read_expression(void *ctx, const char *&src)
while ((expr = read_expression(ctx, src)) != NULL) {
list->subexpressions.push_tail(expr);
}
- if (sscanf(src, " %c%n", &c, &n) != 1 || c != ')') {
+ src += strspn(src, " \v\t\r\n");
+ if (src[0] != ')') {
printf("Unclosed expression (check your parenthesis).\n");
return NULL;
}
- src += n;
+ ++src;
return list;
}
return NULL;
diff --git a/src/glsl/s_expression.h b/src/glsl/s_expression.h
index 1a0c03c2189..aa22475a1bf 100644
--- a/src/glsl/s_expression.h
+++ b/src/glsl/s_expression.h
@@ -113,7 +113,7 @@ private:
class s_symbol : public s_expression
{
public:
- s_symbol(const char *);
+ s_symbol(const char *, size_t);
bool is_symbol() const { return true; }