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

Jose Fonseca jfonseca at vmware.com
Mon Aug 13 10:02:43 PDT 2012


I'm not familiar with this code in detail, but sound good to me.

Jose

----- Original Message -----
> 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
> 
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
> 


More information about the mesa-dev mailing list