[Mesa-dev] [PATCH 05/19] gallium/tgsi: fix TGSI text parser

Marek Olšák maraeo at gmail.com
Thu Aug 9 09:07:17 PDT 2012


The problem was that the string matching succeeded e.g. for "2D" when there
was actually "2D_MSAA" and then failed parsing "_MSAA".

To prevent similar failures in the future, let's fix this kind of error
everywhere.
---
 src/gallium/auxiliary/tgsi/tgsi_text.c |  174 ++++++++++++++++++--------------
 1 file changed, 97 insertions(+), 77 deletions(-)

diff --git a/src/gallium/auxiliary/tgsi/tgsi_text.c b/src/gallium/auxiliary/tgsi/tgsi_text.c
index f2bf49e..68d1478 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_text.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_text.c
@@ -81,6 +81,11 @@ streq_nocase_uprcase(const char *str1,
    return *str1 == 0 && *str2 == 0;
 }
 
+/* Return TRUE if both strings match.
+ * The second string is terminated by zero.
+ * The pointer to the first string is moved at end of the read word
+ * on success.
+ */
 static boolean str_match_no_case( const char **pcur, const char *str )
 {
    const char *cur = *pcur;
@@ -96,6 +101,24 @@ static boolean str_match_no_case( const char **pcur, const char *str )
    return FALSE;
 }
 
+/* Return TRUE if both strings match.
+ * The first string is be terminated by a non-digit non-letter non-underscore
+ * character, the second string is terminated by zero.
+ * The pointer to the first string is moved at end of the read word
+ * on success.
+ */
+static boolean str_match_nocase_whole( const char **pcur, const char *str )
+{
+   const char *cur = *pcur;
+
+   if (str_match_no_case(&cur, str) &&
+       !is_digit_alpha_underscore(cur)) {
+      *pcur = cur;
+      return TRUE;
+   }
+   return FALSE;
+}
+
 /* Eat zero or more whitespaces.
  */
 static void eat_opt_white( const char **pcur )
@@ -249,13 +272,13 @@ static boolean parse_header( struct translate_ctx *ctx )
 {
    uint processor;
 
-   if (str_match_no_case( &ctx->cur, "FRAG" ))
+   if (str_match_nocase_whole( &ctx->cur, "FRAG" ))
       processor = TGSI_PROCESSOR_FRAGMENT;
-   else if (str_match_no_case( &ctx->cur, "VERT" ))
+   else if (str_match_nocase_whole( &ctx->cur, "VERT" ))
       processor = TGSI_PROCESSOR_VERTEX;
-   else if (str_match_no_case( &ctx->cur, "GEOM" ))
+   else if (str_match_nocase_whole( &ctx->cur, "GEOM" ))
       processor = TGSI_PROCESSOR_GEOMETRY;
-   else if (str_match_no_case( &ctx->cur, "COMP" ))
+   else if (str_match_nocase_whole( &ctx->cur, "COMP" ))
       processor = TGSI_PROCESSOR_COMPUTE;
    else {
       report_error( ctx, "Unknown header" );
@@ -298,12 +321,10 @@ parse_file( const char **pcur, uint *file )
    for (i = 0; i < TGSI_FILE_COUNT; i++) {
       const char *cur = *pcur;
 
-      if (str_match_no_case( &cur, tgsi_file_names[i] )) {
-         if (!is_digit_alpha_underscore( cur )) {
-            *pcur = cur;
-            *file = i;
-            return TRUE;
-         }
+      if (str_match_nocase_whole( &cur, tgsi_file_names[i] )) {
+         *pcur = cur;
+         *file = i;
+         return TRUE;
       }
    }
    return FALSE;
@@ -806,12 +827,34 @@ parse_src_operand(
 }
 
 static boolean
-match_inst_mnemonic(const char **pcur,
-                    const struct tgsi_opcode_info *info)
+match_inst(const char **pcur,
+           unsigned *saturate,
+           const struct tgsi_opcode_info *info)
 {
-   if (str_match_no_case(pcur, info->mnemonic)) {
+   const char *cur = *pcur;
+
+   /* simple case: the whole string matches the instruction name */
+   if (str_match_nocase_whole(&cur, info->mnemonic)) {
+      *pcur = cur;
+      *saturate = TGSI_SAT_NONE;
       return TRUE;
    }
+
+   if (str_match_no_case(&cur, info->mnemonic)) {
+      /* the instruction has a suffix, figure it out */
+      if (str_match_nocase_whole(&cur, "_SAT")) {
+         *pcur = cur;
+         *saturate = TGSI_SAT_ZERO_ONE;
+         return TRUE;
+      }
+
+      if (str_match_nocase_whole(&cur, "_SATNV")) {
+         *pcur = cur;
+         *saturate = TGSI_SAT_MINUS_PLUS_ONE;
+         return TRUE;
+      }
+   }
+
    return FALSE;
 }
 
@@ -873,17 +916,10 @@ parse_instruction(
       cur = ctx->cur;
 
       info = tgsi_get_opcode_info( i );
-      if (match_inst_mnemonic(&cur, info)) {
-         if (str_match_no_case( &cur, "_SATNV" ))
-            saturate = TGSI_SAT_MINUS_PLUS_ONE;
-         else if (str_match_no_case( &cur, "_SAT" ))
-            saturate = TGSI_SAT_ZERO_ONE;
-
+      if (match_inst(&cur, &saturate, info)) {
          if (info->num_dst + info->num_src + info->is_tex == 0) {
-            if (!is_digit_alpha_underscore( cur )) {
-               ctx->cur = cur;
-               break;
-            }
+            ctx->cur = cur;
+            break;
          }
          else if (*cur == '\0' || eat_white( &cur )) {
             ctx->cur = cur;
@@ -929,12 +965,10 @@ parse_instruction(
          uint j;
 
          for (j = 0; j < TGSI_TEXTURE_COUNT; j++) {
-            if (str_match_no_case( &ctx->cur, tgsi_texture_names[j] )) {
-               if (!is_digit_alpha_underscore( ctx->cur )) {
-                  inst.Instruction.Texture = 1;
-                  inst.Texture.Texture = j;
-                  break;
-               }
+            if (str_match_nocase_whole( &ctx->cur, tgsi_texture_names[j] )) {
+               inst.Instruction.Texture = 1;
+               inst.Texture.Texture = j;
+               break;
             }
          }
          if (j == TGSI_TEXTURE_COUNT) {
@@ -1077,11 +1111,9 @@ static boolean parse_declaration( struct translate_ctx *ctx )
       eat_opt_white( &cur );
       if (file == TGSI_FILE_RESOURCE) {
          for (i = 0; i < TGSI_TEXTURE_COUNT; i++) {
-            if (str_match_no_case(&cur, tgsi_texture_names[i])) {
-               if (!is_digit_alpha_underscore(cur)) {
-                  decl.Resource.Resource = i;
-                  break;
-               }
+            if (str_match_nocase_whole(&cur, tgsi_texture_names[i])) {
+               decl.Resource.Resource = i;
+               break;
             }
          }
          if (i == TGSI_TEXTURE_COUNT) {
@@ -1094,12 +1126,10 @@ static boolean parse_declaration( struct translate_ctx *ctx )
          while (*cur2 == ',') {
             cur2++;
             eat_opt_white(&cur2);
-            if (str_match_no_case(&cur2, "RAW") &&
-                !is_digit_alpha_underscore(cur2)) {
+            if (str_match_nocase_whole(&cur2, "RAW")) {
                decl.Resource.Raw = 1;
 
-            } else if (str_match_no_case(&cur2, "WR") &&
-                !is_digit_alpha_underscore(cur2)) {
+            } else if (str_match_nocase_whole(&cur2, "WR")) {
                decl.Resource.Writable = 1;
 
             } else {
@@ -1113,11 +1143,9 @@ static boolean parse_declaration( struct translate_ctx *ctx )
 
       } else if (file == TGSI_FILE_SAMPLER_VIEW) {
          for (i = 0; i < TGSI_TEXTURE_COUNT; i++) {
-            if (str_match_no_case(&cur, tgsi_texture_names[i])) {
-               if (!is_digit_alpha_underscore(cur)) {
-                  decl.SamplerView.Resource = i;
-                  break;
-               }
+            if (str_match_nocase_whole(&cur, tgsi_texture_names[i])) {
+               decl.SamplerView.Resource = i;
+               break;
             }
          }
          if (i == TGSI_TEXTURE_COUNT) {
@@ -1133,26 +1161,24 @@ static boolean parse_declaration( struct translate_ctx *ctx )
          eat_opt_white( &cur );
          for (j = 0; j < 4; ++j) {
             for (i = 0; i < PIPE_TYPE_COUNT; ++i) {
-               if (str_match_no_case(&cur, tgsi_type_names[i])) {
-                  if (!is_digit_alpha_underscore(cur)) {
-                     switch (j) {
-                     case 0:
-                        decl.SamplerView.ReturnTypeX = i;
-                        break;
-                     case 1:
-                        decl.SamplerView.ReturnTypeY = i;
-                        break;
-                     case 2:
-                        decl.SamplerView.ReturnTypeZ = i;
-                        break;
-                     case 3:
-                        decl.SamplerView.ReturnTypeW = i;
-                        break;
-                     default:
-                        assert(0);
-                     }
+               if (str_match_nocase_whole(&cur, tgsi_type_names[i])) {
+                  switch (j) {
+                  case 0:
+                     decl.SamplerView.ReturnTypeX = i;
+                     break;
+                  case 1:
+                     decl.SamplerView.ReturnTypeY = i;
+                     break;
+                  case 2:
+                     decl.SamplerView.ReturnTypeZ = i;
                      break;
+                  case 3:
+                     decl.SamplerView.ReturnTypeW = i;
+                     break;
+                  default:
+                     assert(0);
                   }
+                  break;
                }
             }
             if (i == PIPE_TYPE_COUNT) {
@@ -1181,8 +1207,7 @@ static boolean parse_declaration( struct translate_ctx *ctx )
          }
          ctx->cur = cur;
       } else {
-         if (str_match_no_case(&cur, "LOCAL") &&
-             !is_digit_alpha_underscore(cur)) {
+         if (str_match_nocase_whole(&cur, "LOCAL")) {
             decl.Declaration.Local = 1;
             ctx->cur = cur;
          }
@@ -1194,11 +1219,9 @@ static boolean parse_declaration( struct translate_ctx *ctx )
             eat_opt_white( &cur );
 
             for (i = 0; i < TGSI_SEMANTIC_COUNT; i++) {
-               if (str_match_no_case( &cur, tgsi_semantic_names[i] )) {
+               if (str_match_nocase_whole(&cur, tgsi_semantic_names[i])) {
                   uint index;
 
-                  if (is_digit_alpha_underscore( cur ))
-                     continue;
                   cur2 = cur;
                   eat_opt_white( &cur2 );
                   if (*cur2 == '[') {
@@ -1277,9 +1300,7 @@ static boolean parse_declaration( struct translate_ctx *ctx )
       cur++;
       eat_opt_white( &cur );
       for (i = 0; i < TGSI_INTERPOLATE_COUNT; i++) {
-         if (str_match_no_case( &cur, tgsi_interpolate_names[i] )) {
-            if (is_digit_alpha_underscore( cur ))
-               continue;
+         if (str_match_nocase_whole( &cur, tgsi_interpolate_names[i] )) {
             decl.Declaration.Interpolate = 1;
             decl.Interp.Interpolate = i;
 
@@ -1320,8 +1341,7 @@ static boolean parse_immediate( struct translate_ctx *ctx )
       return FALSE;
    }
    for (type = 0; type < Elements(tgsi_immediate_type_names); ++type) {
-      if (str_match_no_case(&ctx->cur, tgsi_immediate_type_names[type]) &&
-          !is_digit_alpha_underscore(ctx->cur))
+      if (str_match_nocase_whole(&ctx->cur, tgsi_immediate_type_names[type]))
          break;
    }
    if (type == Elements(tgsi_immediate_type_names)) {
@@ -1354,7 +1374,7 @@ parse_primitive( const char **pcur, uint *primitive )
    for (i = 0; i < PIPE_PRIM_MAX; i++) {
       const char *cur = *pcur;
 
-      if (str_match_no_case( &cur, tgsi_primitive_names[i])) {
+      if (str_match_nocase_whole( &cur, tgsi_primitive_names[i])) {
          *primitive = i;
          *pcur = cur;
          return TRUE;
@@ -1371,7 +1391,7 @@ parse_fs_coord_origin( const char **pcur, uint *fs_coord_origin )
    for (i = 0; i < Elements(tgsi_fs_coord_origin_names); i++) {
       const char *cur = *pcur;
 
-      if (str_match_no_case( &cur, tgsi_fs_coord_origin_names[i])) {
+      if (str_match_nocase_whole( &cur, tgsi_fs_coord_origin_names[i])) {
          *fs_coord_origin = i;
          *pcur = cur;
          return TRUE;
@@ -1388,7 +1408,7 @@ parse_fs_coord_pixel_center( const char **pcur, uint *fs_coord_pixel_center )
    for (i = 0; i < Elements(tgsi_fs_coord_pixel_center_names); i++) {
       const char *cur = *pcur;
 
-      if (str_match_no_case( &cur, tgsi_fs_coord_pixel_center_names[i])) {
+      if (str_match_nocase_whole( &cur, tgsi_fs_coord_pixel_center_names[i])) {
          *fs_coord_pixel_center = i;
          *pcur = cur;
          return TRUE;
@@ -1495,15 +1515,15 @@ static boolean translate( struct translate_ctx *ctx )
          if (!parse_instruction( ctx, TRUE ))
             return FALSE;
       }
-      else if (str_match_no_case( &ctx->cur, "DCL" )) {
+      else if (str_match_nocase_whole( &ctx->cur, "DCL" )) {
          if (!parse_declaration( ctx ))
             return FALSE;
       }
-      else if (str_match_no_case( &ctx->cur, "IMM" )) {
+      else if (str_match_nocase_whole( &ctx->cur, "IMM" )) {
          if (!parse_immediate( ctx ))
             return FALSE;
       }
-      else if (str_match_no_case( &ctx->cur, "PROPERTY" )) {
+      else if (str_match_nocase_whole( &ctx->cur, "PROPERTY" )) {
          if (!parse_property( ctx ))
             return FALSE;
       }
-- 
1.7.9.5



More information about the mesa-dev mailing list