Mesa (master): glsl: Replace sscanf in s_expression reader with strspn and strcspn.

Kenneth Graunke kwg at kemper.freedesktop.org
Thu Aug 19 04:29:42 UTC 2010


Module: Mesa
Branch: master
Commit: 365ce61997a28a0c0dad79e7d3f7616e57f105f5
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=365ce61997a28a0c0dad79e7d3f7616e57f105f5

Author: Kenneth Graunke <kenneth at whitecape.org>
Date:   Wed Aug 18 18:03:22 2010 -0700

glsl: Replace sscanf in s_expression reader with strspn and strcspn.

This seems to give roughly a 20% speedup.

---

 src/glsl/s_expression.cpp |   49 ++++++++++++++++++++++++++------------------
 src/glsl/s_expression.h   |    2 +-
 2 files changed, 30 insertions(+), 21 deletions(-)

diff --git a/src/glsl/s_expression.cpp b/src/glsl/s_expression.cpp
index 26be23e..4458c48 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 1a0c03c..aa22475 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; }
 




More information about the mesa-commit mailing list