Mesa (master): Revert "ARB prog parser: Fix epic memory leak in lexer / parser interface"

Ian Romanick idr at kemper.freedesktop.org
Fri Nov 6 19:21:54 UTC 2009


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

Author: Ian Romanick <ian.d.romanick at intel.com>
Date:   Wed Nov  4 12:03:44 2009 -0800

Revert "ARB prog parser: Fix epic memory leak in lexer / parser interface"

This reverts commit 93dae6761bc90bbd43b450d2673620ec189b2c7a.

This change was completely broken when the parser uses multiple
strings in a single production.  It would be nice if bug fixes could
initially land somewhere other than the stable branch.

---

 src/mesa/shader/lex.yy.c            |  445 +++++++++++++++-------------------
 src/mesa/shader/program_lexer.l     |   45 +----
 src/mesa/shader/program_parse.tab.c |   21 +--
 src/mesa/shader/program_parse.y     |   17 +-
 src/mesa/shader/program_parser.h    |   16 --
 5 files changed, 207 insertions(+), 337 deletions(-)

diff --git a/src/mesa/shader/lex.yy.c b/src/mesa/shader/lex.yy.c
index 728c2dc..fefef57 100644
--- a/src/mesa/shader/lex.yy.c
+++ b/src/mesa/shader/lex.yy.c
@@ -53,6 +53,7 @@ typedef int flex_int32_t;
 typedef unsigned char flex_uint8_t; 
 typedef unsigned short int flex_uint16_t;
 typedef unsigned int flex_uint32_t;
+#endif /* ! C99 */
 
 /* Limits of integral types. */
 #ifndef INT8_MIN
@@ -83,8 +84,6 @@ typedef unsigned int flex_uint32_t;
 #define UINT32_MAX             (4294967295U)
 #endif
 
-#endif /* ! C99 */
-
 #endif /* ! FLEXINT_H */
 
 #ifdef __cplusplus
@@ -158,15 +157,7 @@ typedef void* yyscan_t;
 
 /* Size of default input buffer. */
 #ifndef YY_BUF_SIZE
-#ifdef __ia64__
-/* On IA-64, the buffer size is 16k, not 8k.
- * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case.
- * Ditto for the __ia64__ case accordingly.
- */
-#define YY_BUF_SIZE 32768
-#else
 #define YY_BUF_SIZE 16384
-#endif /* __ia64__ */
 #endif
 
 /* The state buf must be large enough to hold one state per character in the main buffer.
@@ -927,7 +918,7 @@ static yyconst flex_int16_t yy_chk[1023] =
       if (condition) {					\
 	 return token;					\
       } else {						\
-	 yylval->string = return_string(yyextra, yytext);	\
+	 yylval->string = strdup(yytext);		\
 	 return IDENTIFIER;				\
       }							\
    } while (0)
@@ -950,7 +941,7 @@ static yyconst flex_int16_t yy_chk[1023] =
 	 yylval->temp_inst.SaturateMode = SATURATE_ ## sat; \
 	 return token;					\
       } else {						\
-	 yylval->string = return_string(yyextra, yytext);		\
+	 yylval->string = strdup(yytext);		\
 	 return IDENTIFIER;				\
       }							\
    } while (0)
@@ -958,45 +949,6 @@ static yyconst flex_int16_t yy_chk[1023] =
 #define SWIZZLE_INVAL  MAKE_SWIZZLE4(SWIZZLE_NIL, SWIZZLE_NIL, \
 				     SWIZZLE_NIL, SWIZZLE_NIL)
 
-/**
- * Send a string to the parser using asm_parser_state::string_dumpster
- *
- * Sends a string to the parser using asm_parser_state::string_dumpster as a
- * temporary storage buffer.  Data previously stored in
- * asm_parser_state::string_dumpster will be lost.  If
- * asm_parser_state::string_dumpster is not large enough to hold the new
- * string, the buffer size will be increased.  The buffer size is \b never
- * decreased.
- *
- * \param state   Assembler parser state tracking
- * \param str     String to be passed to the parser
- *
- * \return
- * A pointer to asm_parser_state::string_dumpster on success or \c NULL on
- * failure.  Currently the only failure case is \c ENOMEM.
- */
-static char *
-return_string(struct asm_parser_state *state, const char *str)
-{
-   const size_t len = strlen(str);
-
-   if (len >= state->dumpster_size) {
-      char *const dumpster = _mesa_realloc(state->string_dumpster,
-					   state->dumpster_size,
-					   len + 1);
-      if (dumpster == NULL) {
-	 return NULL;
-      }
-
-      state->string_dumpster = dumpster;
-      state->dumpster_size = len + 1;
-   }
-
-   memcpy(state->string_dumpster, str, len + 1);
-   return state->string_dumpster;
-}
-
-
 static unsigned
 mask_from_char(char c)
 {
@@ -1052,7 +1004,7 @@ swiz_from_char(char c)
    } while(0);
 
 #define YY_EXTRA_TYPE struct asm_parser_state *
-#line 1056 "lex.yy.c"
+#line 1008 "lex.yy.c"
 
 #define INITIAL 0
 
@@ -1189,12 +1141,7 @@ static int input (yyscan_t yyscanner );
 
 /* Amount of stuff to slurp up with each read. */
 #ifndef YY_READ_BUF_SIZE
-#ifdef __ia64__
-/* On IA-64, the buffer size is 16k, not 8k */
-#define YY_READ_BUF_SIZE 16384
-#else
 #define YY_READ_BUF_SIZE 8192
-#endif /* __ia64__ */
 #endif
 
 /* Copy whatever the last rule matched to the standard output. */
@@ -1202,7 +1149,7 @@ static int input (yyscan_t yyscanner );
 /* This used to be an fputs(), but since the string might contain NUL's,
  * we now use fwrite().
  */
-#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0)
+#define ECHO fwrite( yytext, yyleng, 1, yyout )
 #endif
 
 /* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
@@ -1213,7 +1160,7 @@ static int input (yyscan_t yyscanner );
 	if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
 		{ \
 		int c = '*'; \
-		size_t n; \
+		unsigned n; \
 		for ( n = 0; n < max_size && \
 			     (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
 			buf[n] = (char) c; \
@@ -1298,10 +1245,10 @@ YY_DECL
 	register int yy_act;
     struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
 
-#line 176 "program_lexer.l"
+#line 137 "program_lexer.l"
 
 
-#line 1305 "lex.yy.c"
+#line 1252 "lex.yy.c"
 
     yylval = yylval_param;
 
@@ -1390,17 +1337,17 @@ do_action:	/* This label is used only to access EOF actions. */
 
 case 1:
 YY_RULE_SETUP
-#line 178 "program_lexer.l"
+#line 139 "program_lexer.l"
 { return ARBvp_10; }
 	YY_BREAK
 case 2:
 YY_RULE_SETUP
-#line 179 "program_lexer.l"
+#line 140 "program_lexer.l"
 { return ARBfp_10; }
 	YY_BREAK
 case 3:
 YY_RULE_SETUP
-#line 180 "program_lexer.l"
+#line 141 "program_lexer.l"
 {
    yylval->integer = at_address;
    return_token_or_IDENTIFIER(require_ARB_vp, ADDRESS);
@@ -1408,760 +1355,760 @@ YY_RULE_SETUP
 	YY_BREAK
 case 4:
 YY_RULE_SETUP
-#line 184 "program_lexer.l"
+#line 145 "program_lexer.l"
 { return ALIAS; }
 	YY_BREAK
 case 5:
 YY_RULE_SETUP
-#line 185 "program_lexer.l"
+#line 146 "program_lexer.l"
 { return ATTRIB; }
 	YY_BREAK
 case 6:
 YY_RULE_SETUP
-#line 186 "program_lexer.l"
+#line 147 "program_lexer.l"
 { return END; }
 	YY_BREAK
 case 7:
 YY_RULE_SETUP
-#line 187 "program_lexer.l"
+#line 148 "program_lexer.l"
 { return OPTION; }
 	YY_BREAK
 case 8:
 YY_RULE_SETUP
-#line 188 "program_lexer.l"
+#line 149 "program_lexer.l"
 { return OUTPUT; }
 	YY_BREAK
 case 9:
 YY_RULE_SETUP
-#line 189 "program_lexer.l"
+#line 150 "program_lexer.l"
 { return PARAM; }
 	YY_BREAK
 case 10:
 YY_RULE_SETUP
-#line 190 "program_lexer.l"
+#line 151 "program_lexer.l"
 { yylval->integer = at_temp; return TEMP; }
 	YY_BREAK
 case 11:
 YY_RULE_SETUP
-#line 192 "program_lexer.l"
+#line 153 "program_lexer.l"
 { return_opcode(             1, VECTOR_OP, ABS, OFF); }
 	YY_BREAK
 case 12:
 YY_RULE_SETUP
-#line 193 "program_lexer.l"
+#line 154 "program_lexer.l"
 { return_opcode(require_ARB_fp, VECTOR_OP, ABS, ZERO_ONE); }
 	YY_BREAK
 case 13:
 YY_RULE_SETUP
-#line 194 "program_lexer.l"
+#line 155 "program_lexer.l"
 { return_opcode(             1, BIN_OP, ADD, OFF); }
 	YY_BREAK
 case 14:
 YY_RULE_SETUP
-#line 195 "program_lexer.l"
+#line 156 "program_lexer.l"
 { return_opcode(require_ARB_fp, BIN_OP, ADD, ZERO_ONE); }
 	YY_BREAK
 case 15:
 YY_RULE_SETUP
-#line 196 "program_lexer.l"
+#line 157 "program_lexer.l"
 { return_opcode(require_ARB_vp, ARL, ARL, OFF); }
 	YY_BREAK
 case 16:
 YY_RULE_SETUP
-#line 198 "program_lexer.l"
+#line 159 "program_lexer.l"
 { return_opcode(require_ARB_fp, TRI_OP, CMP, OFF); }
 	YY_BREAK
 case 17:
 YY_RULE_SETUP
-#line 199 "program_lexer.l"
+#line 160 "program_lexer.l"
 { return_opcode(require_ARB_fp, TRI_OP, CMP, ZERO_ONE); }
 	YY_BREAK
 case 18:
 YY_RULE_SETUP
-#line 200 "program_lexer.l"
+#line 161 "program_lexer.l"
 { return_opcode(require_ARB_fp, SCALAR_OP, COS, OFF); }
 	YY_BREAK
 case 19:
 YY_RULE_SETUP
-#line 201 "program_lexer.l"
+#line 162 "program_lexer.l"
 { return_opcode(require_ARB_fp, SCALAR_OP, COS, ZERO_ONE); }
 	YY_BREAK
 case 20:
 YY_RULE_SETUP
-#line 203 "program_lexer.l"
+#line 164 "program_lexer.l"
 { return_opcode(             1, BIN_OP, DP3, OFF); }
 	YY_BREAK
 case 21:
 YY_RULE_SETUP
-#line 204 "program_lexer.l"
+#line 165 "program_lexer.l"
 { return_opcode(require_ARB_fp, BIN_OP, DP3, ZERO_ONE); }
 	YY_BREAK
 case 22:
 YY_RULE_SETUP
-#line 205 "program_lexer.l"
+#line 166 "program_lexer.l"
 { return_opcode(             1, BIN_OP, DP4, OFF); }
 	YY_BREAK
 case 23:
 YY_RULE_SETUP
-#line 206 "program_lexer.l"
+#line 167 "program_lexer.l"
 { return_opcode(require_ARB_fp, BIN_OP, DP4, ZERO_ONE); }
 	YY_BREAK
 case 24:
 YY_RULE_SETUP
-#line 207 "program_lexer.l"
+#line 168 "program_lexer.l"
 { return_opcode(             1, BIN_OP, DPH, OFF); }
 	YY_BREAK
 case 25:
 YY_RULE_SETUP
-#line 208 "program_lexer.l"
+#line 169 "program_lexer.l"
 { return_opcode(require_ARB_fp, BIN_OP, DPH, ZERO_ONE); }
 	YY_BREAK
 case 26:
 YY_RULE_SETUP
-#line 209 "program_lexer.l"
+#line 170 "program_lexer.l"
 { return_opcode(             1, BIN_OP, DST, OFF); }
 	YY_BREAK
 case 27:
 YY_RULE_SETUP
-#line 210 "program_lexer.l"
+#line 171 "program_lexer.l"
 { return_opcode(require_ARB_fp, BIN_OP, DST, ZERO_ONE); }
 	YY_BREAK
 case 28:
 YY_RULE_SETUP
-#line 212 "program_lexer.l"
+#line 173 "program_lexer.l"
 { return_opcode(             1, SCALAR_OP, EX2, OFF); }
 	YY_BREAK
 case 29:
 YY_RULE_SETUP
-#line 213 "program_lexer.l"
+#line 174 "program_lexer.l"
 { return_opcode(require_ARB_fp, SCALAR_OP, EX2, ZERO_ONE); }
 	YY_BREAK
 case 30:
 YY_RULE_SETUP
-#line 214 "program_lexer.l"
+#line 175 "program_lexer.l"
 { return_opcode(require_ARB_vp, SCALAR_OP, EXP, OFF); }
 	YY_BREAK
 case 31:
 YY_RULE_SETUP
-#line 216 "program_lexer.l"
+#line 177 "program_lexer.l"
 { return_opcode(             1, VECTOR_OP, FLR, OFF); }
 	YY_BREAK
 case 32:
 YY_RULE_SETUP
-#line 217 "program_lexer.l"
+#line 178 "program_lexer.l"
 { return_opcode(require_ARB_fp, VECTOR_OP, FLR, ZERO_ONE); }
 	YY_BREAK
 case 33:
 YY_RULE_SETUP
-#line 218 "program_lexer.l"
+#line 179 "program_lexer.l"
 { return_opcode(             1, VECTOR_OP, FRC, OFF); }
 	YY_BREAK
 case 34:
 YY_RULE_SETUP
-#line 219 "program_lexer.l"
+#line 180 "program_lexer.l"
 { return_opcode(require_ARB_fp, VECTOR_OP, FRC, ZERO_ONE); }
 	YY_BREAK
 case 35:
 YY_RULE_SETUP
-#line 221 "program_lexer.l"
+#line 182 "program_lexer.l"
 { return_opcode(require_ARB_fp, KIL, KIL, OFF); }
 	YY_BREAK
 case 36:
 YY_RULE_SETUP
-#line 223 "program_lexer.l"
+#line 184 "program_lexer.l"
 { return_opcode(             1, VECTOR_OP, LIT, OFF); }
 	YY_BREAK
 case 37:
 YY_RULE_SETUP
-#line 224 "program_lexer.l"
+#line 185 "program_lexer.l"
 { return_opcode(require_ARB_fp, VECTOR_OP, LIT, ZERO_ONE); }
 	YY_BREAK
 case 38:
 YY_RULE_SETUP
-#line 225 "program_lexer.l"
+#line 186 "program_lexer.l"
 { return_opcode(             1, SCALAR_OP, LG2, OFF); }
 	YY_BREAK
 case 39:
 YY_RULE_SETUP
-#line 226 "program_lexer.l"
+#line 187 "program_lexer.l"
 { return_opcode(require_ARB_fp, SCALAR_OP, LG2, ZERO_ONE); }
 	YY_BREAK
 case 40:
 YY_RULE_SETUP
-#line 227 "program_lexer.l"
+#line 188 "program_lexer.l"
 { return_opcode(require_ARB_vp, SCALAR_OP, LOG, OFF); }
 	YY_BREAK
 case 41:
 YY_RULE_SETUP
-#line 228 "program_lexer.l"
+#line 189 "program_lexer.l"
 { return_opcode(require_ARB_fp, TRI_OP, LRP, OFF); }
 	YY_BREAK
 case 42:
 YY_RULE_SETUP
-#line 229 "program_lexer.l"
+#line 190 "program_lexer.l"
 { return_opcode(require_ARB_fp, TRI_OP, LRP, ZERO_ONE); }
 	YY_BREAK
 case 43:
 YY_RULE_SETUP
-#line 231 "program_lexer.l"
+#line 192 "program_lexer.l"
 { return_opcode(             1, TRI_OP, MAD, OFF); }
 	YY_BREAK
 case 44:
 YY_RULE_SETUP
-#line 232 "program_lexer.l"
+#line 193 "program_lexer.l"
 { return_opcode(require_ARB_fp, TRI_OP, MAD, ZERO_ONE); }
 	YY_BREAK
 case 45:
 YY_RULE_SETUP
-#line 233 "program_lexer.l"
+#line 194 "program_lexer.l"
 { return_opcode(             1, BIN_OP, MAX, OFF); }
 	YY_BREAK
 case 46:
 YY_RULE_SETUP
-#line 234 "program_lexer.l"
+#line 195 "program_lexer.l"
 { return_opcode(require_ARB_fp, BIN_OP, MAX, ZERO_ONE); }
 	YY_BREAK
 case 47:
 YY_RULE_SETUP
-#line 235 "program_lexer.l"
+#line 196 "program_lexer.l"
 { return_opcode(             1, BIN_OP, MIN, OFF); }
 	YY_BREAK
 case 48:
 YY_RULE_SETUP
-#line 236 "program_lexer.l"
+#line 197 "program_lexer.l"
 { return_opcode(require_ARB_fp, BIN_OP, MIN, ZERO_ONE); }
 	YY_BREAK
 case 49:
 YY_RULE_SETUP
-#line 237 "program_lexer.l"
+#line 198 "program_lexer.l"
 { return_opcode(             1, VECTOR_OP, MOV, OFF); }
 	YY_BREAK
 case 50:
 YY_RULE_SETUP
-#line 238 "program_lexer.l"
+#line 199 "program_lexer.l"
 { return_opcode(require_ARB_fp, VECTOR_OP, MOV, ZERO_ONE); }
 	YY_BREAK
 case 51:
 YY_RULE_SETUP
-#line 239 "program_lexer.l"
+#line 200 "program_lexer.l"
 { return_opcode(             1, BIN_OP, MUL, OFF); }
 	YY_BREAK
 case 52:
 YY_RULE_SETUP
-#line 240 "program_lexer.l"
+#line 201 "program_lexer.l"
 { return_opcode(require_ARB_fp, BIN_OP, MUL, ZERO_ONE); }
 	YY_BREAK
 case 53:
 YY_RULE_SETUP
-#line 242 "program_lexer.l"
+#line 203 "program_lexer.l"
 { return_opcode(             1, BINSC_OP, POW, OFF); }
 	YY_BREAK
 case 54:
 YY_RULE_SETUP
-#line 243 "program_lexer.l"
+#line 204 "program_lexer.l"
 { return_opcode(require_ARB_fp, BINSC_OP, POW, ZERO_ONE); }
 	YY_BREAK
 case 55:
 YY_RULE_SETUP
-#line 245 "program_lexer.l"
+#line 206 "program_lexer.l"
 { return_opcode(             1, SCALAR_OP, RCP, OFF); }
 	YY_BREAK
 case 56:
 YY_RULE_SETUP
-#line 246 "program_lexer.l"
+#line 207 "program_lexer.l"
 { return_opcode(require_ARB_fp, SCALAR_OP, RCP, ZERO_ONE); }
 	YY_BREAK
 case 57:
 YY_RULE_SETUP
-#line 247 "program_lexer.l"
+#line 208 "program_lexer.l"
 { return_opcode(             1, SCALAR_OP, RSQ, OFF); }
 	YY_BREAK
 case 58:
 YY_RULE_SETUP
-#line 248 "program_lexer.l"
+#line 209 "program_lexer.l"
 { return_opcode(require_ARB_fp, SCALAR_OP, RSQ, ZERO_ONE); }
 	YY_BREAK
 case 59:
 YY_RULE_SETUP
-#line 250 "program_lexer.l"
+#line 211 "program_lexer.l"
 { return_opcode(require_ARB_fp, SCALAR_OP, SCS, OFF); }
 	YY_BREAK
 case 60:
 YY_RULE_SETUP
-#line 251 "program_lexer.l"
+#line 212 "program_lexer.l"
 { return_opcode(require_ARB_fp, SCALAR_OP, SCS, ZERO_ONE); }
 	YY_BREAK
 case 61:
 YY_RULE_SETUP
-#line 252 "program_lexer.l"
+#line 213 "program_lexer.l"
 { return_opcode(             1, BIN_OP, SGE, OFF); }
 	YY_BREAK
 case 62:
 YY_RULE_SETUP
-#line 253 "program_lexer.l"
+#line 214 "program_lexer.l"
 { return_opcode(require_ARB_fp, BIN_OP, SGE, ZERO_ONE); }
 	YY_BREAK
 case 63:
 YY_RULE_SETUP
-#line 254 "program_lexer.l"
+#line 215 "program_lexer.l"
 { return_opcode(require_ARB_fp, SCALAR_OP, SIN, OFF); }
 	YY_BREAK
 case 64:
 YY_RULE_SETUP
-#line 255 "program_lexer.l"
+#line 216 "program_lexer.l"
 { return_opcode(require_ARB_fp, SCALAR_OP, SIN, ZERO_ONE); }
 	YY_BREAK
 case 65:
 YY_RULE_SETUP
-#line 256 "program_lexer.l"
+#line 217 "program_lexer.l"
 { return_opcode(             1, BIN_OP, SLT, OFF); }
 	YY_BREAK
 case 66:
 YY_RULE_SETUP
-#line 257 "program_lexer.l"
+#line 218 "program_lexer.l"
 { return_opcode(require_ARB_fp, BIN_OP, SLT, ZERO_ONE); }
 	YY_BREAK
 case 67:
 YY_RULE_SETUP
-#line 258 "program_lexer.l"
+#line 219 "program_lexer.l"
 { return_opcode(             1, BIN_OP, SUB, OFF); }
 	YY_BREAK
 case 68:
 YY_RULE_SETUP
-#line 259 "program_lexer.l"
+#line 220 "program_lexer.l"
 { return_opcode(require_ARB_fp, BIN_OP, SUB, ZERO_ONE); }
 	YY_BREAK
 case 69:
 YY_RULE_SETUP
-#line 260 "program_lexer.l"
+#line 221 "program_lexer.l"
 { return_opcode(             1, SWZ, SWZ, OFF); }
 	YY_BREAK
 case 70:
 YY_RULE_SETUP
-#line 261 "program_lexer.l"
+#line 222 "program_lexer.l"
 { return_opcode(require_ARB_fp, SWZ, SWZ, ZERO_ONE); }
 	YY_BREAK
 case 71:
 YY_RULE_SETUP
-#line 263 "program_lexer.l"
+#line 224 "program_lexer.l"
 { return_opcode(require_ARB_fp, SAMPLE_OP, TEX, OFF); }
 	YY_BREAK
 case 72:
 YY_RULE_SETUP
-#line 264 "program_lexer.l"
+#line 225 "program_lexer.l"
 { return_opcode(require_ARB_fp, SAMPLE_OP, TEX, ZERO_ONE); }
 	YY_BREAK
 case 73:
 YY_RULE_SETUP
-#line 265 "program_lexer.l"
+#line 226 "program_lexer.l"
 { return_opcode(require_ARB_fp, SAMPLE_OP, TXB, OFF); }
 	YY_BREAK
 case 74:
 YY_RULE_SETUP
-#line 266 "program_lexer.l"
+#line 227 "program_lexer.l"
 { return_opcode(require_ARB_fp, SAMPLE_OP, TXB, ZERO_ONE); }
 	YY_BREAK
 case 75:
 YY_RULE_SETUP
-#line 267 "program_lexer.l"
+#line 228 "program_lexer.l"
 { return_opcode(require_ARB_fp, SAMPLE_OP, TXP, OFF); }
 	YY_BREAK
 case 76:
 YY_RULE_SETUP
-#line 268 "program_lexer.l"
+#line 229 "program_lexer.l"
 { return_opcode(require_ARB_fp, SAMPLE_OP, TXP, ZERO_ONE); }
 	YY_BREAK
 case 77:
 YY_RULE_SETUP
-#line 270 "program_lexer.l"
+#line 231 "program_lexer.l"
 { return_opcode(             1, BIN_OP, XPD, OFF); }
 	YY_BREAK
 case 78:
 YY_RULE_SETUP
-#line 271 "program_lexer.l"
+#line 232 "program_lexer.l"
 { return_opcode(require_ARB_fp, BIN_OP, XPD, ZERO_ONE); }
 	YY_BREAK
 case 79:
 YY_RULE_SETUP
-#line 273 "program_lexer.l"
+#line 234 "program_lexer.l"
 { return_token_or_IDENTIFIER(require_ARB_vp, VERTEX); }
 	YY_BREAK
 case 80:
 YY_RULE_SETUP
-#line 274 "program_lexer.l"
+#line 235 "program_lexer.l"
 { return_token_or_IDENTIFIER(require_ARB_fp, FRAGMENT); }
 	YY_BREAK
 case 81:
 YY_RULE_SETUP
-#line 275 "program_lexer.l"
+#line 236 "program_lexer.l"
 { return PROGRAM; }
 	YY_BREAK
 case 82:
 YY_RULE_SETUP
-#line 276 "program_lexer.l"
+#line 237 "program_lexer.l"
 { return STATE; }
 	YY_BREAK
 case 83:
 YY_RULE_SETUP
-#line 277 "program_lexer.l"
+#line 238 "program_lexer.l"
 { return RESULT; }
 	YY_BREAK
 case 84:
 YY_RULE_SETUP
-#line 279 "program_lexer.l"
+#line 240 "program_lexer.l"
 { return AMBIENT; }
 	YY_BREAK
 case 85:
 YY_RULE_SETUP
-#line 280 "program_lexer.l"
+#line 241 "program_lexer.l"
 { return ATTENUATION; }
 	YY_BREAK
 case 86:
 YY_RULE_SETUP
-#line 281 "program_lexer.l"
+#line 242 "program_lexer.l"
 { return BACK; }
 	YY_BREAK
 case 87:
 YY_RULE_SETUP
-#line 282 "program_lexer.l"
+#line 243 "program_lexer.l"
 { return_token_or_DOT(require_ARB_vp, CLIP); }
 	YY_BREAK
 case 88:
 YY_RULE_SETUP
-#line 283 "program_lexer.l"
+#line 244 "program_lexer.l"
 { return COLOR; }
 	YY_BREAK
 case 89:
 YY_RULE_SETUP
-#line 284 "program_lexer.l"
+#line 245 "program_lexer.l"
 { return_token_or_DOT(require_ARB_fp, DEPTH); }
 	YY_BREAK
 case 90:
 YY_RULE_SETUP
-#line 285 "program_lexer.l"
+#line 246 "program_lexer.l"
 { return DIFFUSE; }
 	YY_BREAK
 case 91:
 YY_RULE_SETUP
-#line 286 "program_lexer.l"
+#line 247 "program_lexer.l"
 { return DIRECTION; }
 	YY_BREAK
 case 92:
 YY_RULE_SETUP
-#line 287 "program_lexer.l"
+#line 248 "program_lexer.l"
 { return EMISSION; }
 	YY_BREAK
 case 93:
 YY_RULE_SETUP
-#line 288 "program_lexer.l"
+#line 249 "program_lexer.l"
 { return ENV; }
 	YY_BREAK
 case 94:
 YY_RULE_SETUP
-#line 289 "program_lexer.l"
+#line 250 "program_lexer.l"
 { return EYE; }
 	YY_BREAK
 case 95:
 YY_RULE_SETUP
-#line 290 "program_lexer.l"
+#line 251 "program_lexer.l"
 { return FOGCOORD; }
 	YY_BREAK
 case 96:
 YY_RULE_SETUP
-#line 291 "program_lexer.l"
+#line 252 "program_lexer.l"
 { return FOG; }
 	YY_BREAK
 case 97:
 YY_RULE_SETUP
-#line 292 "program_lexer.l"
+#line 253 "program_lexer.l"
 { return FRONT; }
 	YY_BREAK
 case 98:
 YY_RULE_SETUP
-#line 293 "program_lexer.l"
+#line 254 "program_lexer.l"
 { return HALF; }
 	YY_BREAK
 case 99:
 YY_RULE_SETUP
-#line 294 "program_lexer.l"
+#line 255 "program_lexer.l"
 { return INVERSE; }
 	YY_BREAK
 case 100:
 YY_RULE_SETUP
-#line 295 "program_lexer.l"
+#line 256 "program_lexer.l"
 { return INVTRANS; }
 	YY_BREAK
 case 101:
 YY_RULE_SETUP
-#line 296 "program_lexer.l"
+#line 257 "program_lexer.l"
 { return LIGHT; }
 	YY_BREAK
 case 102:
 YY_RULE_SETUP
-#line 297 "program_lexer.l"
+#line 258 "program_lexer.l"
 { return LIGHTMODEL; }
 	YY_BREAK
 case 103:
 YY_RULE_SETUP
-#line 298 "program_lexer.l"
+#line 259 "program_lexer.l"
 { return LIGHTPROD; }
 	YY_BREAK
 case 104:
 YY_RULE_SETUP
-#line 299 "program_lexer.l"
+#line 260 "program_lexer.l"
 { return LOCAL; }
 	YY_BREAK
 case 105:
 YY_RULE_SETUP
-#line 300 "program_lexer.l"
+#line 261 "program_lexer.l"
 { return MATERIAL; }
 	YY_BREAK
 case 106:
 YY_RULE_SETUP
-#line 301 "program_lexer.l"
+#line 262 "program_lexer.l"
 { return MAT_PROGRAM; }
 	YY_BREAK
 case 107:
 YY_RULE_SETUP
-#line 302 "program_lexer.l"
+#line 263 "program_lexer.l"
 { return MATRIX; }
 	YY_BREAK
 case 108:
 YY_RULE_SETUP
-#line 303 "program_lexer.l"
+#line 264 "program_lexer.l"
 { return_token_or_DOT(require_ARB_vp, MATRIXINDEX); }
 	YY_BREAK
 case 109:
 YY_RULE_SETUP
-#line 304 "program_lexer.l"
+#line 265 "program_lexer.l"
 { return MODELVIEW; }
 	YY_BREAK
 case 110:
 YY_RULE_SETUP
-#line 305 "program_lexer.l"
+#line 266 "program_lexer.l"
 { return MVP; }
 	YY_BREAK
 case 111:
 YY_RULE_SETUP
-#line 306 "program_lexer.l"
+#line 267 "program_lexer.l"
 { return_token_or_DOT(require_ARB_vp, NORMAL); }
 	YY_BREAK
 case 112:
 YY_RULE_SETUP
-#line 307 "program_lexer.l"
+#line 268 "program_lexer.l"
 { return OBJECT; }
 	YY_BREAK
 case 113:
 YY_RULE_SETUP
-#line 308 "program_lexer.l"
+#line 269 "program_lexer.l"
 { return PALETTE; }
 	YY_BREAK
 case 114:
 YY_RULE_SETUP
-#line 309 "program_lexer.l"
+#line 270 "program_lexer.l"
 { return PARAMS; }
 	YY_BREAK
 case 115:
 YY_RULE_SETUP
-#line 310 "program_lexer.l"
+#line 271 "program_lexer.l"
 { return PLANE; }
 	YY_BREAK
 case 116:
 YY_RULE_SETUP
-#line 311 "program_lexer.l"
+#line 272 "program_lexer.l"
 { return_token_or_DOT(require_ARB_vp, POINT_TOK); }
 	YY_BREAK
 case 117:
 YY_RULE_SETUP
-#line 312 "program_lexer.l"
+#line 273 "program_lexer.l"
 { return_token_or_DOT(require_ARB_vp, POINTSIZE); }
 	YY_BREAK
 case 118:
 YY_RULE_SETUP
-#line 313 "program_lexer.l"
+#line 274 "program_lexer.l"
 { return POSITION; }
 	YY_BREAK
 case 119:
 YY_RULE_SETUP
-#line 314 "program_lexer.l"
+#line 275 "program_lexer.l"
 { return PRIMARY; }
 	YY_BREAK
 case 120:
 YY_RULE_SETUP
-#line 315 "program_lexer.l"
+#line 276 "program_lexer.l"
 { return PROJECTION; }
 	YY_BREAK
 case 121:
 YY_RULE_SETUP
-#line 316 "program_lexer.l"
+#line 277 "program_lexer.l"
 { return_token_or_DOT(require_ARB_fp, RANGE); }
 	YY_BREAK
 case 122:
 YY_RULE_SETUP
-#line 317 "program_lexer.l"
+#line 278 "program_lexer.l"
 { return ROW; }
 	YY_BREAK
 case 123:
 YY_RULE_SETUP
-#line 318 "program_lexer.l"
+#line 279 "program_lexer.l"
 { return SCENECOLOR; }
 	YY_BREAK
 case 124:
 YY_RULE_SETUP
-#line 319 "program_lexer.l"
+#line 280 "program_lexer.l"
 { return SECONDARY; }
 	YY_BREAK
 case 125:
 YY_RULE_SETUP
-#line 320 "program_lexer.l"
+#line 281 "program_lexer.l"
 { return SHININESS; }
 	YY_BREAK
 case 126:
 YY_RULE_SETUP
-#line 321 "program_lexer.l"
+#line 282 "program_lexer.l"
 { return_token_or_DOT(require_ARB_vp, SIZE_TOK); }
 	YY_BREAK
 case 127:
 YY_RULE_SETUP
-#line 322 "program_lexer.l"
+#line 283 "program_lexer.l"
 { return SPECULAR; }
 	YY_BREAK
 case 128:
 YY_RULE_SETUP
-#line 323 "program_lexer.l"
+#line 284 "program_lexer.l"
 { return SPOT; }
 	YY_BREAK
 case 129:
 YY_RULE_SETUP
-#line 324 "program_lexer.l"
+#line 285 "program_lexer.l"
 { return TEXCOORD; }
 	YY_BREAK
 case 130:
 YY_RULE_SETUP
-#line 325 "program_lexer.l"
+#line 286 "program_lexer.l"
 { return_token_or_DOT(require_ARB_fp, TEXENV); }
 	YY_BREAK
 case 131:
 YY_RULE_SETUP
-#line 326 "program_lexer.l"
+#line 287 "program_lexer.l"
 { return_token_or_DOT(require_ARB_vp, TEXGEN); }
 	YY_BREAK
 case 132:
 YY_RULE_SETUP
-#line 327 "program_lexer.l"
+#line 288 "program_lexer.l"
 { return_token_or_DOT(require_ARB_vp, TEXGEN_Q); }
 	YY_BREAK
 case 133:
 YY_RULE_SETUP
-#line 328 "program_lexer.l"
+#line 289 "program_lexer.l"
 { return_token_or_DOT(require_ARB_vp, TEXGEN_S); }
 	YY_BREAK
 case 134:
 YY_RULE_SETUP
-#line 329 "program_lexer.l"
+#line 290 "program_lexer.l"
 { return_token_or_DOT(require_ARB_vp, TEXGEN_T); }
 	YY_BREAK
 case 135:
 YY_RULE_SETUP
-#line 330 "program_lexer.l"
+#line 291 "program_lexer.l"
 { return TEXTURE; }
 	YY_BREAK
 case 136:
 YY_RULE_SETUP
-#line 331 "program_lexer.l"
+#line 292 "program_lexer.l"
 { return TRANSPOSE; }
 	YY_BREAK
 case 137:
 YY_RULE_SETUP
-#line 332 "program_lexer.l"
+#line 293 "program_lexer.l"
 { return_token_or_DOT(require_ARB_vp, VTXATTRIB); }
 	YY_BREAK
 case 138:
 YY_RULE_SETUP
-#line 333 "program_lexer.l"
+#line 294 "program_lexer.l"
 { return_token_or_DOT(require_ARB_vp, WEIGHT); }
 	YY_BREAK
 case 139:
 YY_RULE_SETUP
-#line 335 "program_lexer.l"
+#line 296 "program_lexer.l"
 { return_token_or_IDENTIFIER(require_ARB_fp, TEXTURE_UNIT); }
 	YY_BREAK
 case 140:
 YY_RULE_SETUP
-#line 336 "program_lexer.l"
+#line 297 "program_lexer.l"
 { return_token_or_IDENTIFIER(require_ARB_fp, TEX_1D); }
 	YY_BREAK
 case 141:
 YY_RULE_SETUP
-#line 337 "program_lexer.l"
+#line 298 "program_lexer.l"
 { return_token_or_IDENTIFIER(require_ARB_fp, TEX_2D); }
 	YY_BREAK
 case 142:
 YY_RULE_SETUP
-#line 338 "program_lexer.l"
+#line 299 "program_lexer.l"
 { return_token_or_IDENTIFIER(require_ARB_fp, TEX_3D); }
 	YY_BREAK
 case 143:
 YY_RULE_SETUP
-#line 339 "program_lexer.l"
+#line 300 "program_lexer.l"
 { return_token_or_IDENTIFIER(require_ARB_fp, TEX_CUBE); }
 	YY_BREAK
 case 144:
 YY_RULE_SETUP
-#line 340 "program_lexer.l"
+#line 301 "program_lexer.l"
 { return_token_or_IDENTIFIER(require_ARB_fp && require_rect, TEX_RECT); }
 	YY_BREAK
 case 145:
 YY_RULE_SETUP
-#line 341 "program_lexer.l"
+#line 302 "program_lexer.l"
 { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow, TEX_SHADOW1D); }
 	YY_BREAK
 case 146:
 YY_RULE_SETUP
-#line 342 "program_lexer.l"
+#line 303 "program_lexer.l"
 { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow, TEX_SHADOW2D); }
 	YY_BREAK
 case 147:
 YY_RULE_SETUP
-#line 343 "program_lexer.l"
+#line 304 "program_lexer.l"
 { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow && require_rect, TEX_SHADOWRECT); }
 	YY_BREAK
 case 148:
 YY_RULE_SETUP
-#line 344 "program_lexer.l"
+#line 305 "program_lexer.l"
 { return_token_or_IDENTIFIER(require_ARB_fp && require_texarray, TEX_ARRAY1D); }
 	YY_BREAK
 case 149:
 YY_RULE_SETUP
-#line 345 "program_lexer.l"
+#line 306 "program_lexer.l"
 { return_token_or_IDENTIFIER(require_ARB_fp && require_texarray, TEX_ARRAY2D); }
 	YY_BREAK
 case 150:
 YY_RULE_SETUP
-#line 346 "program_lexer.l"
+#line 307 "program_lexer.l"
 { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow && require_texarray, TEX_ARRAYSHADOW1D); }
 	YY_BREAK
 case 151:
 YY_RULE_SETUP
-#line 347 "program_lexer.l"
+#line 308 "program_lexer.l"
 { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow && require_texarray, TEX_ARRAYSHADOW2D); }
 	YY_BREAK
 case 152:
 YY_RULE_SETUP
-#line 349 "program_lexer.l"
+#line 310 "program_lexer.l"
 {
-   yylval->string = return_string(yyextra, yytext);
+   yylval->string = strdup(yytext);
    return IDENTIFIER;
 }
 	YY_BREAK
 case 153:
 YY_RULE_SETUP
-#line 354 "program_lexer.l"
+#line 315 "program_lexer.l"
 { return DOT_DOT; }
 	YY_BREAK
 case 154:
 YY_RULE_SETUP
-#line 356 "program_lexer.l"
+#line 317 "program_lexer.l"
 {
    yylval->integer = strtol(yytext, NULL, 10);
    return INTEGER;
@@ -2169,7 +2116,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 155:
 YY_RULE_SETUP
-#line 360 "program_lexer.l"
+#line 321 "program_lexer.l"
 {
    yylval->real = _mesa_strtod(yytext, NULL);
    return REAL;
@@ -2181,7 +2128,7 @@ case 156:
 yyg->yy_c_buf_p = yy_cp -= 1;
 YY_DO_BEFORE_ACTION; /* set up yytext again */
 YY_RULE_SETUP
-#line 364 "program_lexer.l"
+#line 325 "program_lexer.l"
 {
    yylval->real = _mesa_strtod(yytext, NULL);
    return REAL;
@@ -2189,7 +2136,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 157:
 YY_RULE_SETUP
-#line 368 "program_lexer.l"
+#line 329 "program_lexer.l"
 {
    yylval->real = _mesa_strtod(yytext, NULL);
    return REAL;
@@ -2197,7 +2144,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 158:
 YY_RULE_SETUP
-#line 372 "program_lexer.l"
+#line 333 "program_lexer.l"
 {
    yylval->real = _mesa_strtod(yytext, NULL);
    return REAL;
@@ -2205,7 +2152,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 159:
 YY_RULE_SETUP
-#line 377 "program_lexer.l"
+#line 338 "program_lexer.l"
 {
    yylval->swiz_mask.swizzle = SWIZZLE_NOOP;
    yylval->swiz_mask.mask = WRITEMASK_XYZW;
@@ -2214,7 +2161,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 160:
 YY_RULE_SETUP
-#line 383 "program_lexer.l"
+#line 344 "program_lexer.l"
 {
    yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
    yylval->swiz_mask.mask = WRITEMASK_XY
@@ -2224,7 +2171,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 161:
 YY_RULE_SETUP
-#line 389 "program_lexer.l"
+#line 350 "program_lexer.l"
 {
    yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
    yylval->swiz_mask.mask = WRITEMASK_XZW;
@@ -2233,7 +2180,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 162:
 YY_RULE_SETUP
-#line 394 "program_lexer.l"
+#line 355 "program_lexer.l"
 {
    yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
    yylval->swiz_mask.mask = WRITEMASK_YZW;
@@ -2242,7 +2189,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 163:
 YY_RULE_SETUP
-#line 400 "program_lexer.l"
+#line 361 "program_lexer.l"
 {
    yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
    yylval->swiz_mask.mask = WRITEMASK_X
@@ -2252,7 +2199,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 164:
 YY_RULE_SETUP
-#line 406 "program_lexer.l"
+#line 367 "program_lexer.l"
 {
    yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
    yylval->swiz_mask.mask = WRITEMASK_Y
@@ -2262,7 +2209,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 165:
 YY_RULE_SETUP
-#line 412 "program_lexer.l"
+#line 373 "program_lexer.l"
 {
    yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
    yylval->swiz_mask.mask = WRITEMASK_ZW;
@@ -2271,7 +2218,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 166:
 YY_RULE_SETUP
-#line 418 "program_lexer.l"
+#line 379 "program_lexer.l"
 {
    const unsigned s = swiz_from_char(yytext[1]);
    yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(s, s, s, s);
@@ -2281,7 +2228,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 167:
 YY_RULE_SETUP
-#line 425 "program_lexer.l"
+#line 386 "program_lexer.l"
 {
    yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(swiz_from_char(yytext[1]),
 					    swiz_from_char(yytext[2]),
@@ -2293,7 +2240,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 168:
 YY_RULE_SETUP
-#line 434 "program_lexer.l"
+#line 395 "program_lexer.l"
 {
    yylval->swiz_mask.swizzle = SWIZZLE_NOOP;
    yylval->swiz_mask.mask = WRITEMASK_XYZW;
@@ -2302,7 +2249,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 169:
 YY_RULE_SETUP
-#line 440 "program_lexer.l"
+#line 401 "program_lexer.l"
 {
    yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
    yylval->swiz_mask.mask = WRITEMASK_XY
@@ -2312,7 +2259,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 170:
 YY_RULE_SETUP
-#line 446 "program_lexer.l"
+#line 407 "program_lexer.l"
 {
    yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
    yylval->swiz_mask.mask = WRITEMASK_XZW;
@@ -2321,7 +2268,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 171:
 YY_RULE_SETUP
-#line 451 "program_lexer.l"
+#line 412 "program_lexer.l"
 {
    yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
    yylval->swiz_mask.mask = WRITEMASK_YZW;
@@ -2330,7 +2277,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 172:
 YY_RULE_SETUP
-#line 457 "program_lexer.l"
+#line 418 "program_lexer.l"
 {
    yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
    yylval->swiz_mask.mask = WRITEMASK_X
@@ -2340,7 +2287,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 173:
 YY_RULE_SETUP
-#line 463 "program_lexer.l"
+#line 424 "program_lexer.l"
 {
    yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
    yylval->swiz_mask.mask = WRITEMASK_Y
@@ -2350,7 +2297,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 174:
 YY_RULE_SETUP
-#line 469 "program_lexer.l"
+#line 430 "program_lexer.l"
 {
    yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
    yylval->swiz_mask.mask = WRITEMASK_ZW;
@@ -2359,7 +2306,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 175:
 YY_RULE_SETUP
-#line 475 "program_lexer.l"
+#line 436 "program_lexer.l"
 {
    const unsigned s = swiz_from_char(yytext[1]);
    yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(s, s, s, s);
@@ -2369,7 +2316,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 176:
 YY_RULE_SETUP
-#line 483 "program_lexer.l"
+#line 444 "program_lexer.l"
 {
    if (require_ARB_vp) {
       return TEXGEN_R;
@@ -2383,7 +2330,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 177:
 YY_RULE_SETUP
-#line 494 "program_lexer.l"
+#line 455 "program_lexer.l"
 {
    yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(swiz_from_char(yytext[1]),
 					    swiz_from_char(yytext[2]),
@@ -2395,13 +2342,13 @@ YY_RULE_SETUP
 	YY_BREAK
 case 178:
 YY_RULE_SETUP
-#line 503 "program_lexer.l"
+#line 464 "program_lexer.l"
 { return DOT; }
 	YY_BREAK
 case 179:
 /* rule 179 can match eol */
 YY_RULE_SETUP
-#line 505 "program_lexer.l"
+#line 466 "program_lexer.l"
 {
    yylloc->first_line++;
    yylloc->first_column = 1;
@@ -2412,7 +2359,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 180:
 YY_RULE_SETUP
-#line 512 "program_lexer.l"
+#line 473 "program_lexer.l"
 /* eat whitespace */ ;
 	YY_BREAK
 case 181:
@@ -2420,20 +2367,20 @@ case 181:
 yyg->yy_c_buf_p = yy_cp -= 1;
 YY_DO_BEFORE_ACTION; /* set up yytext again */
 YY_RULE_SETUP
-#line 513 "program_lexer.l"
+#line 474 "program_lexer.l"
 /* eat comments */ ;
 	YY_BREAK
 case 182:
 YY_RULE_SETUP
-#line 514 "program_lexer.l"
+#line 475 "program_lexer.l"
 { return yytext[0]; }
 	YY_BREAK
 case 183:
 YY_RULE_SETUP
-#line 515 "program_lexer.l"
+#line 476 "program_lexer.l"
 ECHO;
 	YY_BREAK
-#line 2437 "lex.yy.c"
+#line 2384 "lex.yy.c"
 case YY_STATE_EOF(INITIAL):
 	yyterminate();
 
@@ -3201,8 +3148,8 @@ YY_BUFFER_STATE yy_scan_string (yyconst char * yystr , yyscan_t yyscanner)
 
 /** Setup the input buffer state to scan the given bytes. The next call to yylex() will
  * scan from a @e copy of @a bytes.
- * @param yybytes the byte buffer to scan
- * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
+ * @param bytes the byte buffer to scan
+ * @param len the number of bytes in the buffer pointed to by @a bytes.
  * @param yyscanner The scanner object.
  * @return the newly allocated buffer state object.
  */
@@ -3608,7 +3555,7 @@ void yyfree (void * ptr , yyscan_t yyscanner)
 
 #define YYTABLES_NAME "yytables"
 
-#line 515 "program_lexer.l"
+#line 476 "program_lexer.l"
 
 
 
diff --git a/src/mesa/shader/program_lexer.l b/src/mesa/shader/program_lexer.l
index 6c4fad3..c2803ff 100644
--- a/src/mesa/shader/program_lexer.l
+++ b/src/mesa/shader/program_lexer.l
@@ -40,7 +40,7 @@
       if (condition) {					\
 	 return token;					\
       } else {						\
-	 yylval->string = return_string(yyextra, yytext);	\
+	 yylval->string = strdup(yytext);		\
 	 return IDENTIFIER;				\
       }							\
    } while (0)
@@ -63,7 +63,7 @@
 	 yylval->temp_inst.SaturateMode = SATURATE_ ## sat; \
 	 return token;					\
       } else {						\
-	 yylval->string = return_string(yyextra, yytext);		\
+	 yylval->string = strdup(yytext);		\
 	 return IDENTIFIER;				\
       }							\
    } while (0)
@@ -71,45 +71,6 @@
 #define SWIZZLE_INVAL  MAKE_SWIZZLE4(SWIZZLE_NIL, SWIZZLE_NIL, \
 				     SWIZZLE_NIL, SWIZZLE_NIL)
 
-/**
- * Send a string to the parser using asm_parser_state::string_dumpster
- *
- * Sends a string to the parser using asm_parser_state::string_dumpster as a
- * temporary storage buffer.  Data previously stored in
- * asm_parser_state::string_dumpster will be lost.  If
- * asm_parser_state::string_dumpster is not large enough to hold the new
- * string, the buffer size will be increased.  The buffer size is \b never
- * decreased.
- *
- * \param state   Assembler parser state tracking
- * \param str     String to be passed to the parser
- *
- * \return
- * A pointer to asm_parser_state::string_dumpster on success or \c NULL on
- * failure.  Currently the only failure case is \c ENOMEM.
- */
-static char *
-return_string(struct asm_parser_state *state, const char *str)
-{
-   const size_t len = strlen(str);
-
-   if (len >= state->dumpster_size) {
-      char *const dumpster = _mesa_realloc(state->string_dumpster,
-					   state->dumpster_size,
-					   len + 1);
-      if (dumpster == NULL) {
-	 return NULL;
-      }
-
-      state->string_dumpster = dumpster;
-      state->dumpster_size = len + 1;
-   }
-
-   memcpy(state->string_dumpster, str, len + 1);
-   return state->string_dumpster;
-}
-
-
 static unsigned
 mask_from_char(char c)
 {
@@ -347,7 +308,7 @@ ARRAYSHADOW1D             { return_token_or_IDENTIFIER(require_ARB_fp && require
 ARRAYSHADOW2D             { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow && require_texarray, TEX_ARRAYSHADOW2D); }
 
 [_a-zA-Z$][_a-zA-Z0-9$]*  {
-   yylval->string = return_string(yyextra, yytext);
+   yylval->string = strdup(yytext);
    return IDENTIFIER;
 }
 
diff --git a/src/mesa/shader/program_parse.tab.c b/src/mesa/shader/program_parse.tab.c
index 261b605..c255e91 100644
--- a/src/mesa/shader/program_parse.tab.c
+++ b/src/mesa/shader/program_parse.tab.c
@@ -4565,7 +4565,7 @@ yyreduce:
 		      "undefined variable binding in ALIAS statement");
 	      YYERROR;
 	   } else {
-	      _mesa_symbol_table_add_symbol(state->st, 0, strdup((yyvsp[(2) - (4)].string)), target);
+	      _mesa_symbol_table_add_symbol(state->st, 0, (yyvsp[(2) - (4)].string), target);
 	   }
 	;}
     break;
@@ -4896,14 +4896,10 @@ declare_variable(struct asm_parser_state *state, char *name, enum asm_type t,
    if (exist != NULL) {
       yyerror(locp, state, "redeclared identifier");
    } else {
-      const size_t name_len = strlen(name);
-
-      s = calloc(1, sizeof(struct asm_symbol) + name_len + 1);
-      s->name = (char *)(s + 1);
+      s = calloc(1, sizeof(struct asm_symbol));
+      s->name = name;
       s->type = t;
 
-      memcpy((char *) s->name, name, name_len + 1);
-
       switch (t) {
       case at_temp:
 	 if (state->prog->NumTemporaries >= state->limits->MaxTemps) {
@@ -5151,11 +5147,6 @@ _mesa_parse_arb_program(GLcontext *ctx, GLenum target, const GLubyte *str,
    _mesa_memcpy (strz, str, len);
    strz[len] = '\0';
 
-   if (state->prog->String != NULL) {
-      _mesa_free(state->prog->String);
-      state->prog->String = NULL;
-   }
-
    state->prog->String = strz;
 
    state->st = _mesa_symbol_table_ctor();
@@ -5245,6 +5236,7 @@ error:
    for (sym = state->sym; sym != NULL; sym = temp) {
       temp = sym->next;
 
+      _mesa_free((void *) sym->name);
       _mesa_free(sym);
    }
    state->sym = NULL;
@@ -5252,11 +5244,6 @@ error:
    _mesa_symbol_table_dtor(state->st);
    state->st = NULL;
 
-   if (state->string_dumpster != NULL) {
-      _mesa_free(state->string_dumpster);
-      state->dumpster_size = 0;
-   }
-
    return result;
 }
 
diff --git a/src/mesa/shader/program_parse.y b/src/mesa/shader/program_parse.y
index a23625d..c3152aa 100644
--- a/src/mesa/shader/program_parse.y
+++ b/src/mesa/shader/program_parse.y
@@ -1919,7 +1919,7 @@ ALIAS_statement: ALIAS IDENTIFIER '=' IDENTIFIER
 		      "undefined variable binding in ALIAS statement");
 	      YYERROR;
 	   } else {
-	      _mesa_symbol_table_add_symbol(state->st, 0, strdup($2), target);
+	      _mesa_symbol_table_add_symbol(state->st, 0, $2, target);
 	   }
 	}
 	;
@@ -2027,14 +2027,10 @@ declare_variable(struct asm_parser_state *state, char *name, enum asm_type t,
    if (exist != NULL) {
       yyerror(locp, state, "redeclared identifier");
    } else {
-      const size_t name_len = strlen(name);
-
-      s = calloc(1, sizeof(struct asm_symbol) + name_len + 1);
-      s->name = (char *)(s + 1);
+      s = calloc(1, sizeof(struct asm_symbol));
+      s->name = name;
       s->type = t;
 
-      memcpy((char *) s->name, name, name_len + 1);
-
       switch (t) {
       case at_temp:
 	 if (state->prog->NumTemporaries >= state->limits->MaxTemps) {
@@ -2284,7 +2280,6 @@ _mesa_parse_arb_program(GLcontext *ctx, GLenum target, const GLubyte *str,
 
    if (state->prog->String != NULL) {
       _mesa_free(state->prog->String);
-      state->prog->String = NULL;
    }
 
    state->prog->String = strz;
@@ -2376,6 +2371,7 @@ error:
    for (sym = state->sym; sym != NULL; sym = temp) {
       temp = sym->next;
 
+      _mesa_free((void *) sym->name);
       _mesa_free(sym);
    }
    state->sym = NULL;
@@ -2383,10 +2379,5 @@ error:
    _mesa_symbol_table_dtor(state->st);
    state->st = NULL;
 
-   if (state->string_dumpster != NULL) {
-      _mesa_free(state->string_dumpster);
-      state->dumpster_size = 0;
-   }
-
    return result;
 }
diff --git a/src/mesa/shader/program_parser.h b/src/mesa/shader/program_parser.h
index 8d8b4d8..fa47d84 100644
--- a/src/mesa/shader/program_parser.h
+++ b/src/mesa/shader/program_parser.h
@@ -38,13 +38,6 @@ enum asm_type {
    at_output,
 };
 
-/**
- * \note
- * Objects of this type are allocated as the object plus the name of the
- * symbol.  That is, malloc(sizeof(struct asm_symbol) + strlen(name) + 1).
- * Alternately, asm_symbol::name could be moved to the bottom of the structure
- * and declared as 'char name[0];'.
- */
 struct asm_symbol {
    struct asm_symbol *next;    /**< List linkage for freeing. */
    const char *name;
@@ -165,15 +158,6 @@ struct asm_parser_state {
 
 
    /**
-    * Buffer to hold strings transfered from the lexer to the parser
-    */
-   /*@{*/
-   char *string_dumpster;      /**< String data transfered. */
-   size_t dumpster_size;       /**< Total size, in bytes, of the buffer. */
-   /*@}*/
-
-
-   /**
     * Selected limits copied from gl_constants
     *
     * These are limits from the GL context, but various bits in the program




More information about the mesa-commit mailing list