fix a lot of warnings found with g++
[mesa.git] / src / mesa / main / arbparse.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 5.1
4 *
5 * Copyright (C) 1999-2003 Brian Paul All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25 #define DEBUG_PARSING 0
26
27 /**
28 * \file arbparse.c
29 * ARB_*_program parser core
30 * \author Michal Krol, Karl Rasche
31 */
32
33
34 #include "mtypes.h"
35 #include "glheader.h"
36 #include "context.h"
37 #include "hash.h"
38 #include "imports.h"
39 #include "macros.h"
40 #include "program.h"
41 #include "nvvertprog.h"
42 #include "nvfragprog.h"
43 #include "arbparse.h"
44
45 /* TODO:
46 * Fragment Program Stuff:
47 * -----------------------------------------------------
48 * - How does negating on SWZ work?? If any of the components have a -,
49 * negate?
50 * - how does thing like 'foo[N]' work in src registers?
51 *
52 * - things from Michal's email
53 * + overflow on atoi
54 * + not-overflowing floats (don't use parse_integer..)
55 * + test for 0 on matrix rows, or give a default value to parse_integer()
56 *
57 * + fix multiple cases in switches, that might change
58 * (these are things that are #defined to the same value, but occur
59 * only on fp or vp's, which funkifies the switch statements)
60 * - STATE_TEX_* STATE_CLIP_PLANE, etc and PRECISION_HINT_FASTEST/
61 * PositionInvariant
62 *
63 * - check all limits of number of various variables
64 * + parameters
65 * + modelview matrix number
66 *
67 * - test! test! test!
68 *
69 * Vertex Program Stuff:
70 * -----------------------------------------------------
71 * - Add in cases for vp attribs
72 * + VERTEX_ATTRIB_MATRIXINDEX -- ??
73 *
74 * - ARRAY_INDEX_RELATIVE
75 * - grep for XXX
76 *
77 * Mesa Stuff
78 * -----------------------------------------------------
79 * - vp_src swizzle is GLubyte, fp_src swizzle is GLuint
80 * - fetch state listed in program_parameters list
81 * + WTF should this go???
82 * + currently in nvvertexec.c and s_nvfragprog.c
83 *
84 * - allow for multiple address registers (and fetch address regs properly)
85 *
86 * Cosmetic Stuff
87 * -----------------------------------------------------
88 * - fix compiler warnings
89 * - remove any leftover unused grammer.c stuff (dict_ ?)
90 * - fix grammer.c error handling so its not static
91 * - #ifdef around stuff pertaining to extentions
92 *
93 * Outstanding Questions:
94 * -----------------------------------------------------
95 * - palette matrix? do we support this extension? what is the extention?
96 * - When can we fetch env/local params from their own register files, and
97 * when to we have to fetch them into the main state register file?
98 * (think arrays)
99 *
100 * Grammar Changes:
101 * -----------------------------------------------------
102 */
103
104 typedef GLubyte *production;
105
106 /*-----------------------------------------------------------------------
107 * From here on down is the syntax checking portion
108 */
109
110 /* VERSION: 0.4 */
111
112 /*
113 INTRODUCTION
114 ------------
115
116 The task is to check the syntax of an input string. Input string is a
117 stream of ASCII characters terminated with null-character
118 ('\0'). Checking it using C language is difficult and hard to
119 implement without bugs. It is hard to maintain and change prior to
120 further syntax changes.
121
122 This is because of high redundancy of the C code. Large blocks of code
123 are duplicated with only small changes. Even using macros does not
124 solve the problem, because macros cannot erase the complexity of the
125 code.
126
127 The resolution is to create a new language that will be highly
128 oriented to our task. Once we describe particular syntax, we are
129 done. We can then focus on the code that implements the language. The
130 size and complexity of it is relatively small than the code that
131 directly checks the syntax.
132
133 First, we must implement our new language. Here, the language is
134 implemented in C, but it could also be implemented in any other
135 language. The code is listed below. We must take a good care that it
136 is bug free. This is simple because the code is simple and clean.
137
138 Next, we must describe the syntax of our new language in itself. Once
139 created and checked manually that it is correct, we can use it to
140 check another scripts.
141
142 Note that our new language loading code does not have to check the
143 syntax. It is because we assume that the script describing itself is
144 correct, and other scripts can be syntactically checked by the former
145 script. The loading code must only do semantic checking which leads us
146 to simple resolving references.
147
148 THE LANGUAGE
149 ------------
150
151 Here I will describe the syntax of the new language (further called
152 "Synek"). It is mainly a sequence of declarations terminated by a
153 semicolon. The declaration consists of a symbol, which is an
154 identifier, and its definition. A definition is in turn a sequence of
155 specifiers connected with ".and" or ".or" operator. These operators
156 cannot be mixed together in a one definition. Specifier can be a
157 symbol, string, character, character range or a special keyword
158 ".true" or ".false".
159
160 On the very beginning of the script there is a declaration of a root
161 symbol and is in the form:
162 .syntax <root_symbol>;
163
164 The <root_symbol> must be on of the symbols in declaration
165 sequence. The syntax is correct if the root symbol evaluates to
166 true. A symbol evaluates to true if the definition associated with the
167 symbol evaluates to true. Definition evaluation depends on the
168 operator used to connect specifiers in the definition. If ".and"
169 operator is used, definition evaluates to true if and only if all the
170 specifiers evaluate to true. If ".or" operator is used, definition
171 evalutes to true if any of the specifiers evaluates to true. If
172 definition contains only one specifier, it is evaluated as if it was
173 connected with ".true" keyword by ".and" operator.
174
175 If specifier is a ".true" keyword, it always evaluates to true.
176
177 If specifier is a ".false" keyword, it always evaluates to
178 false. Specifier evaluates to false when it does not evaluate to true.
179
180 Character range specifier is in the form:
181 '<first_character>' - '<second_character>'
182
183 If specifier is a character range, it evaluates to true if character
184 in the stream is greater or equal to <first_character> and less or
185 equal to <second_character>. In that situation the stream pointer is
186 advanced to point to next character in the stream. All C-style escape
187 sequences are supported although trigraph sequences are not. The
188 comparisions are performed on 8-bit unsigned integers.
189
190 Character specifier is in the form:
191 '<single_character>'
192
193 It evaluates to true if the following character range specifier evaluates to
194 true:
195 '<single_character>' - '<single_character>'
196
197 String specifier is in the form:
198 "<string>"
199
200 Let N be the number of characters in <string>. Let <string>[i]
201 designate i-th character in <string>. Then the string specifier
202 evaluates to true if and only if for i in the range [0, N) the
203 following character specifier evaluates to true:
204 '<string>[i]'
205
206 If <string>[i] is a quotation mark, '<string>[i]' is replaced with
207 '\<string>[i]'.
208
209 Symbol specifier can be optionally preceded by a ".loop" keyword in the form:
210 .loop <symbol> (1)
211 where <symbol> is defined as follows:
212 <symbol> <definition>; (2)
213 Construction (1) is replaced by the following code:
214 <symbol$1>
215 and declaration (2) is replaced by the following:
216 <symbol$1> <symbol$2> .or .true;
217 <symbol$2> <symbol> .and <symbol$1>;
218 <symbol> <definition>;
219
220
221 ESCAPE SEQUENCES
222 ----------------
223
224 Synek supports all escape sequences in character specifiers. The
225 mapping table is listed below. All occurences of the characters in
226 the first column are replaced with the corresponding character in the
227 second column.
228
229 Escape sequence Represents
230 -----------------------------------------------------------------------
231 \a Bell (alert)
232 \b Backspace
233 \f Formfeed
234 \n New line
235 \r Carriage return
236 \t Horizontal tab
237 \v Vertical tab
238 \' Single quotation mark
239 \" Double quotation mark
240 \\ Backslash
241 \? Literal question mark
242 \ooo ASCII character in octal notation
243 \xhhh ASCII character in hexadecimal notation
244 -----------------------------------------------------------------------
245
246
247 RAISING ERRORS
248 --------------
249
250 Any specifier can be followed by a special construction that is
251 executed when the specifier evaluates to false. The construction is in
252 the form:
253 .error <ERROR_TEXT>
254
255 <ERROR_TEXT> is an identifier declared earlier by error text
256 declaration. The declaration is in the form:
257
258 .errtext <ERROR_TEXT> "<error_desc>"
259
260 When specifier evaluates to false and this construction is present,
261 parsing is stopped immediately and <error_desc> is returned as a
262 result of parsing. The error position is also returned and it is meant
263 as an offset from the beggining of the stream to the character that
264 was valid so far. Example:
265
266 (**** syntax script ****)
267
268 .syntax program;
269 .errtext MISSING_SEMICOLON "missing ';'"
270 program declaration .and .loop space .and ';'
271 .error MISSING_SEMICOLON .and
272 .loop space .and '\0';
273 declaration "declare" .and .loop space .and identifier;
274 space ' ';
275 (**** sample code ****)
276 declare foo ,
277
278 In the example above checking the sample code will result in error
279 message "missing ';'" and error position 12. The sample code is not
280 correct. Note the presence of '\0' specifier to assure that there is
281 no code after semicolon - only spaces. <error_desc> can optionally
282 contain identifier surrounded by dollar signs $. In such a case, the
283 identifier and dollar signs are replaced by a string retrieved by
284 invoking symbol with the identifier name. The starting position is the
285 error position. The lenght of the resulting string is the position
286 after invoking the symbol.
287
288
289 PRODUCTION
290 ----------
291
292 Synek not only checks the syntax but it can also produce (emit) bytes
293 associated with specifiers that evaluate to true. That is, every
294 specifier and optional error construction can be followed by a number
295 of emit constructions that are in the form:
296 .emit <parameter>
297
298 <paramater> can be a HEX number, identifier, a star * or a dollar
299 $. HEX number is preceded by 0x or 0X. If <parameter> is an
300 identifier, it must be earlier declared by emit code declaration in
301 the form:
302 .emtcode <identifier> <hex_number>
303
304 When given specifier evaluates to true, all emits associated with the
305 specifier are output in order they were declared. A star means that
306 last-read character should be output instead of constant
307 value. Example:
308
309 (**** syntax script ****)
310
311 .syntax foobar;
312 .emtcode WORD_FOO 0x01
313 .emtcode WORD_BAR 0x02
314 foobar FOO .emit WORD_FOO .or BAR .emit WORD_BAR .or .true .emit 0x00;
315 FOO "foo" .and SPACE;
316 BAR "bar" .and SPACE;
317 SPACE ' ' .or '\0';
318
319 (**** sample text 1 ****)
320
321 foo
322
323 (**** sample text 2 ****)
324
325 foobar
326
327 For both samples the result will be one-element array. For first
328 sample text it will be value 1, for second - 0. Note that every text
329 will be accepted because of presence of .true as an alternative.
330
331 Another example:
332
333 (**** syntax script ****)
334
335 .syntax declaration;
336 .emtcode VARIABLE 0x01
337 declaration "declare" .and .loop space .and
338 identifier .emit VARIABLE .and (1)
339 .true .emit 0x00 .and (2)
340 .loop space .and ';';
341 space ' ' .or '\t';
342 identifier .loop id_char .emit *; (3)
343 id_char 'a'-'z' .or 'A'-'Z' .or '_';
344 (**** sample code ****)
345 declare fubar;
346
347 In specifier (1) symbol <identifier> is followed by .emit VARIABLE. If
348 it evaluates to true, VARIABLE constant and then production of the
349 symbol is output. Specifier (2) is used to terminate the string with
350 null to signal when the string ends. Specifier (3) outputs all
351 characters that make declared identifier. The result of sample code
352 will be the following array:
353 { 1, 'f', 'u', 'b', 'a', 'r', 0 }
354
355 If .emit is followed by dollar $, it means that current position
356 should be output. Current position is a 32-bit unsigned integer
357 distance from the very beginning of the parsed string to first
358 character consumed by the specifier associated with the .emit
359 instruction. Current position is stored in the output buffer in
360 Little-Endian convention (the lowest byte comes first). */
361
362
363 /**
364 * This is the text describing the rules to parse the grammar
365 */
366 #include "arbparse_syn.h"
367
368 /**
369 * These should match up with the values defined in arbparse.syn.h
370 */
371
372 #define REVISION 0x04
373
374 /* program type */
375 #define FRAGMENT_PROGRAM 0x01
376 #define VERTEX_PROGRAM 0x02
377
378 /* program section */
379 #define OPTION 0x01
380 #define INSTRUCTION 0x02
381 #define DECLARATION 0x03
382 #define END 0x04
383
384 /* fragment program option flags */
385 #define ARB_PRECISION_HINT_FASTEST 0x01
386 #define ARB_PRECISION_HINT_NICEST 0x02
387 #define ARB_FOG_EXP 0x04
388 #define ARB_FOG_EXP2 0x08
389 #define ARB_FOG_LINEAR 0x10
390
391 /* vertex program option flags */
392 /*
393 $4: changed from 0x01 to 0x20.
394 */
395 #define ARB_POSITION_INVARIANT 0x20
396
397 /* fragment program instruction class */
398 #define F_ALU_INST 0x01
399 #define F_TEX_INST 0x02
400
401 /* fragment program instruction type */
402 #define F_ALU_VECTOR 0x01
403 #define F_ALU_SCALAR 0x02
404 #define F_ALU_BINSC 0x03
405 #define F_ALU_BIN 0x04
406 #define F_ALU_TRI 0x05
407 #define F_ALU_SWZ 0x06
408 #define F_TEX_SAMPLE 0x07
409 #define F_TEX_KIL 0x08
410
411 /* vertex program instruction type */
412 #define V_GEN_ARL 0x01
413 #define V_GEN_VECTOR 0x02
414 #define V_GEN_SCALAR 0x03
415 #define V_GEN_BINSC 0x04
416 #define V_GEN_BIN 0x05
417 #define V_GEN_TRI 0x06
418 #define V_GEN_SWZ 0x07
419
420 /* fragment program instruction code */
421 #define F_ABS 0x00
422 #define F_ABS_SAT 0x01
423 #define F_FLR 0x02
424 #define F_FLR_SAT 0x03
425 #define F_FRC 0x04
426 #define F_FRC_SAT 0x05
427 #define F_LIT 0x06
428 #define F_LIT_SAT 0x07
429 #define F_MOV 0x08
430 #define F_MOV_SAT 0x09
431 #define F_COS 0x0A
432 #define F_COS_SAT 0x0B
433 #define F_EX2 0x0C
434 #define F_EX2_SAT 0x0D
435 #define F_LG2 0x0E
436 #define F_LG2_SAT 0x0F
437 #define F_RCP 0x10
438 #define F_RCP_SAT 0x11
439 #define F_RSQ 0x12
440 #define F_RSQ_SAT 0x13
441 #define F_SIN 0x14
442 #define F_SIN_SAT 0x15
443 #define F_SCS 0x16
444 #define F_SCS_SAT 0x17
445 #define F_POW 0x18
446 #define F_POW_SAT 0x19
447 #define F_ADD 0x1A
448 #define F_ADD_SAT 0x1B
449 #define F_DP3 0x1C
450 #define F_DP3_SAT 0x1D
451 #define F_DP4 0x1E
452 #define F_DP4_SAT 0x1F
453 #define F_DPH 0x20
454 #define F_DPH_SAT 0x21
455 #define F_DST 0x22
456 #define F_DST_SAT 0x23
457 #define F_MAX 0x24
458 #define F_MAX_SAT 0x25
459 #define F_MIN 0x26
460 #define F_MIN_SAT 0x27
461 #define F_MUL 0x28
462 #define F_MUL_SAT 0x29
463 #define F_SGE 0x2A
464 #define F_SGE_SAT 0x2B
465 #define F_SLT 0x2C
466 #define F_SLT_SAT 0x2D
467 #define F_SUB 0x2E
468 #define F_SUB_SAT 0x2F
469 #define F_XPD 0x30
470 #define F_XPD_SAT 0x31
471 #define F_CMP 0x32
472 #define F_CMP_SAT 0x33
473 #define F_LRP 0x34
474 #define F_LRP_SAT 0x35
475 #define F_MAD 0x36
476 #define F_MAD_SAT 0x37
477 #define F_SWZ 0x38
478 #define F_SWZ_SAT 0x39
479 #define F_TEX 0x3A
480 #define F_TEX_SAT 0x3B
481 #define F_TXB 0x3C
482 #define F_TXB_SAT 0x3D
483 #define F_TXP 0x3E
484 #define F_TXP_SAT 0x3F
485 #define F_KIL 0x40
486
487 /* vertex program instruction code */
488 #define V_ARL 0x01
489 #define V_ABS 0x02
490 #define V_FLR 0x03
491 #define V_FRC 0x04
492 #define V_LIT 0x05
493 #define V_MOV 0x06
494 #define V_EX2 0x07
495 #define V_EXP 0x08
496 #define V_LG2 0x09
497 #define V_LOG 0x0A
498 #define V_RCP 0x0B
499 #define V_RSQ 0x0C
500 #define V_POW 0x0D
501 #define V_ADD 0x0E
502 #define V_DP3 0x0F
503 #define V_DP4 0x10
504 #define V_DPH 0x11
505 #define V_DST 0x12
506 #define V_MAX 0x13
507 #define V_MIN 0x14
508 #define V_MUL 0x15
509 #define V_SGE 0x16
510 #define V_SLT 0x17
511 #define V_SUB 0x18
512 #define V_XPD 0x19
513 #define V_MAD 0x1A
514 #define V_SWZ 0x1B
515
516 /* fragment attribute binding */
517 #define FRAGMENT_ATTRIB_COLOR 0x01
518 #define FRAGMENT_ATTRIB_TEXCOORD 0x02
519 #define FRAGMENT_ATTRIB_FOGCOORD 0x03
520 #define FRAGMENT_ATTRIB_POSITION 0x04
521
522 /* vertex attribute binding */
523 #define VERTEX_ATTRIB_POSITION 0x01
524 #define VERTEX_ATTRIB_WEIGHT 0x02
525 #define VERTEX_ATTRIB_NORMAL 0x03
526 #define VERTEX_ATTRIB_COLOR 0x04
527 #define VERTEX_ATTRIB_FOGCOORD 0x05
528 #define VERTEX_ATTRIB_TEXCOORD 0x06
529 #define VERTEX_ATTRIB_MATRIXINDEX 0x07
530 #define VERTEX_ATTRIB_GENERIC 0x08
531
532 /* fragment result binding */
533 #define FRAGMENT_RESULT_COLOR 0x01
534 #define FRAGMENT_RESULT_DEPTH 0x02
535
536 /* vertex result binding */
537 #define VERTEX_RESULT_POSITION 0x01
538 #define VERTEX_RESULT_COLOR 0x02
539 #define VERTEX_RESULT_FOGCOORD 0x03
540 #define VERTEX_RESULT_POINTSIZE 0x04
541 #define VERTEX_RESULT_TEXCOORD 0x05
542
543 /* texture target */
544 #define TEXTARGET_1D 0x01
545 #define TEXTARGET_2D 0x02
546 #define TEXTARGET_3D 0x03
547 #define TEXTARGET_RECT 0x04
548 #define TEXTARGET_CUBE 0x05
549
550 /* sign */
551 /*
552 $3: removed. '+' and '-' are used instead.
553 */
554 /*
555 #define SIGN_PLUS 0x00
556 #define SIGN_MINUS 0x01
557 */
558
559 /* face type */
560 #define FACE_FRONT 0x00
561 #define FACE_BACK 0x01
562
563 /* color type */
564 #define COLOR_PRIMARY 0x00
565 #define COLOR_SECONDARY 0x01
566
567 /* component */
568 /*
569 $3: Added enumerants.
570 */
571 #define COMPONENT_X 0x00
572 #define COMPONENT_Y 0x01
573 #define COMPONENT_Z 0x02
574 #define COMPONENT_W 0x03
575 #define COMPONENT_0 0x04
576 #define COMPONENT_1 0x05
577
578 #define ARRAY_INDEX_ABSOLUTE 0x00
579 #define ARRAY_INDEX_RELATIVE 0x01
580
581 /* matrix name */
582 #define MATRIX_MODELVIEW 0x01
583 #define MATRIX_PROJECTION 0x02
584 #define MATRIX_MVP 0x03
585 #define MATRIX_TEXTURE 0x04
586 #define MATRIX_PALETTE 0x05
587 #define MATRIX_PROGRAM 0x06
588
589 /* matrix modifier */
590 #define MATRIX_MODIFIER_IDENTITY 0x00
591 #define MATRIX_MODIFIER_INVERSE 0x01
592 #define MATRIX_MODIFIER_TRANSPOSE 0x02
593 #define MATRIX_MODIFIER_INVTRANS 0x03
594
595 /* constant type */
596 #define CONSTANT_SCALAR 0x01
597 #define CONSTANT_VECTOR 0x02
598
599 /* program param type */
600 #define PROGRAM_PARAM_ENV 0x01
601 #define PROGRAM_PARAM_LOCAL 0x02
602
603 /* register type */
604 #define REGISTER_ATTRIB 0x01
605 #define REGISTER_PARAM 0x02
606 #define REGISTER_RESULT 0x03
607 #define REGISTER_ESTABLISHED_NAME 0x04
608
609 /* param binding */
610 #define PARAM_NULL 0x00
611 #define PARAM_ARRAY_ELEMENT 0x01
612 #define PARAM_STATE_ELEMENT 0x02
613 #define PARAM_PROGRAM_ELEMENT 0x03
614 #define PARAM_PROGRAM_ELEMENTS 0x04
615 #define PARAM_CONSTANT 0x05
616
617 /* param state property */
618 #define STATE_MATERIAL_PARSER 0x01
619 #define STATE_LIGHT_PARSER 0x02
620 #define STATE_LIGHT_MODEL 0x03
621 #define STATE_LIGHT_PROD 0x04
622 #define STATE_FOG 0x05
623 #define STATE_MATRIX_ROWS 0x06
624 /* fragment program only */
625 #define STATE_TEX_ENV 0x07
626 #define STATE_DEPTH 0x08
627 /* vertex program only */
628 /*
629 $4: incremented all the three emit codes by two to not collide with other STATE_* emit codes.
630 */
631 #define STATE_TEX_GEN 0x09
632 #define STATE_CLIP_PLANE 0x0A
633 #define STATE_POINT 0x0B
634
635 /* state material property */
636 #define MATERIAL_AMBIENT 0x01
637 #define MATERIAL_DIFFUSE 0x02
638 #define MATERIAL_SPECULAR 0x03
639 #define MATERIAL_EMISSION 0x04
640 #define MATERIAL_SHININESS 0x05
641
642 /* state light property */
643 #define LIGHT_AMBIENT 0x01
644 #define LIGHT_DIFFUSE 0x02
645 #define LIGHT_SPECULAR 0x03
646 #define LIGHT_POSITION 0x04
647 #define LIGHT_ATTENUATION 0x05
648 #define LIGHT_HALF 0x06
649 #define LIGHT_SPOT_DIRECTION 0x07
650
651 /* state light model property */
652 #define LIGHT_MODEL_AMBIENT 0x01
653 #define LIGHT_MODEL_SCENECOLOR 0x02
654
655 /* state light product property */
656 #define LIGHT_PROD_AMBIENT 0x01
657 #define LIGHT_PROD_DIFFUSE 0x02
658 #define LIGHT_PROD_SPECULAR 0x03
659
660 /* state texture environment property */
661 #define TEX_ENV_COLOR 0x01
662
663 /* state texture generation coord property */
664 #define TEX_GEN_EYE 0x01
665 #define TEX_GEN_OBJECT 0x02
666
667 /* state fog property */
668 #define FOG_COLOR 0x01
669 #define FOG_PARAMS 0x02
670
671 /* state depth property */
672 #define DEPTH_RANGE 0x01
673
674 /* state point parameters property */
675 #define POINT_SIZE 0x01
676 #define POINT_ATTENUATION 0x02
677
678 /* declaration */
679 #define ATTRIB 0x01
680 #define PARAM 0x02
681 #define TEMP 0x03
682 #define OUTPUT 0x04
683 #define ALIAS 0x05
684 /* vertex program 1.0 only */
685 #define ADDRESS 0x06
686
687 /*
688 memory management routines
689 */
690 static GLvoid *mem_alloc (GLsizei);
691 static GLvoid mem_free (GLvoid **);
692 static GLvoid *mem_realloc (GLvoid *, GLsizei, GLsizei);
693 static GLubyte *str_duplicate (const GLubyte *);
694
695 /*
696 internal error messages
697 */
698 static const GLubyte *OUT_OF_MEMORY =
699 (GLubyte *) "internal error 1001: out of physical memory";
700 static const GLubyte *UNRESOLVED_REFERENCE =
701 (GLubyte *) "internal error 1002: unresolved reference '$'";
702 /*
703 static const GLubyte *INVALID_PARAMETER =
704 (GLubyte *) "internal error 1003: invalid parameter";
705 */
706
707 static const GLubyte *error_message = NULL;
708 static GLubyte *error_param = NULL; /* this is inserted into error_message in place of $ */
709 static GLint error_position = -1;
710
711 static GLubyte *unknown = (GLubyte *) "???";
712
713 static GLvoid
714 clear_last_error ()
715 {
716 /* reset error message */
717 error_message = NULL;
718
719 /* free error parameter - if error_param is a "???" don't free it - it's static */
720 if (error_param != unknown)
721 mem_free ((GLvoid **) & error_param);
722 else
723 error_param = NULL;
724
725 /* reset error position */
726 error_position = -1;
727 }
728
729 static GLvoid
730 set_last_error (const GLubyte * msg, GLubyte * param, GLint pos)
731 {
732 if (error_message != NULL)
733 return;
734
735 error_message = msg;
736 if (param != NULL)
737 error_param = param;
738 else
739 error_param = unknown;
740
741 error_position = pos;
742 }
743
744 /*
745 * memory management routines
746 */
747 static GLvoid *
748 mem_alloc (GLsizei size)
749 {
750 GLvoid *ptr = _mesa_malloc (size);
751 if (ptr == NULL)
752 set_last_error (OUT_OF_MEMORY, NULL, -1);
753 return ptr;
754 }
755
756 static GLvoid
757 mem_free (GLvoid ** ptr)
758 {
759 _mesa_free (*ptr);
760 *ptr = NULL;
761 }
762
763 static GLvoid *
764 mem_realloc (GLvoid * ptr, GLsizei old_size, GLsizei new_size)
765 {
766 GLvoid *ptr2 = _mesa_realloc (ptr, old_size, new_size);
767 if (ptr2 == NULL)
768 set_last_error (OUT_OF_MEMORY, NULL, -1);
769 return ptr2;
770 }
771
772 static GLubyte *
773 str_duplicate (const GLubyte * str)
774 {
775 return (GLubyte *) _mesa_strdup ((const char *) str);
776 }
777
778 /*
779 * emit type typedef
780 */
781 typedef enum emit_type_
782 {
783 et_byte, /* explicit number */
784 et_stream, /* eaten character */
785 et_position /* current position */
786 }
787 emit_type;
788
789 /*
790 * emit typedef
791 */
792 typedef struct emit_
793 {
794 emit_type m_emit_type;
795 GLubyte m_byte; /* et_byte */
796 struct emit_ *m_next;
797 }
798 emit;
799
800 static GLvoid
801 emit_create (emit ** em)
802 {
803 *em = (emit *) mem_alloc (sizeof (emit));
804 if (*em) {
805 (**em).m_emit_type = et_byte;
806 (**em).m_byte = 0;
807 (**em).m_next = NULL;
808 }
809 }
810
811 static GLvoid
812 emit_destroy (emit ** em)
813 {
814 if (*em) {
815 emit_destroy (&(**em).m_next);
816 mem_free ((GLvoid **) em);
817 }
818 }
819
820 static GLvoid
821 emit_append (emit ** em, emit ** ne)
822 {
823 if (*em)
824 emit_append (&(**em).m_next, ne);
825 else
826 *em = *ne;
827 }
828
829 /*
830 * error typedef
831 */
832 typedef struct error_
833 {
834 GLubyte *m_text;
835 GLubyte *m_token_name;
836 struct defntn_ *m_token;
837 }
838 error;
839
840 static GLvoid
841 error_create (error ** er)
842 {
843 *er = (error *) mem_alloc (sizeof (error));
844 if (*er) {
845 (**er).m_text = NULL;
846 (**er).m_token_name = NULL;
847 (**er).m_token = NULL;
848 }
849 }
850
851 static GLvoid
852 error_destroy (error ** er)
853 {
854 if (*er) {
855 mem_free ((GLvoid **) & (**er).m_text);
856 mem_free ((GLvoid **) & (**er).m_token_name);
857 mem_free ((GLvoid **) er);
858 }
859 }
860
861 struct dict_;
862 static GLubyte *error_get_token (error *, struct dict_ *, const GLubyte *, GLuint);
863
864 /*
865 * specifier type typedef
866 */
867 typedef enum spec_type_
868 {
869 st_false,
870 st_true,
871 st_byte,
872 st_byte_range,
873 st_string,
874 st_identifier,
875 st_identifier_loop,
876 st_debug
877 } spec_type;
878
879
880 /*
881 * specifier typedef
882 */
883 typedef struct spec_
884 {
885 spec_type m_spec_type;
886 GLubyte m_byte[2]; /* st_byte, st_byte_range */
887 GLubyte *m_string; /* st_string */
888 struct defntn_ *m_defntn; /* st_identifier, st_identifier_loop */
889 emit *m_emits;
890 error *m_errtext;
891 struct spec_ *m_next;
892 } spec;
893
894
895 static GLvoid
896 spec_create (spec ** sp)
897 {
898 *sp = (spec *) mem_alloc (sizeof (spec));
899 if (*sp) {
900 (**sp).m_spec_type = st_false;
901 (**sp).m_byte[0] = '\0';
902 (**sp).m_byte[1] = '\0';
903 (**sp).m_string = NULL;
904 (**sp).m_defntn = NULL;
905 (**sp).m_emits = NULL;
906 (**sp).m_errtext = NULL;
907 (**sp).m_next = NULL;
908 }
909 }
910
911 static GLvoid
912 spec_destroy (spec ** sp)
913 {
914 if (*sp) {
915 spec_destroy (&(**sp).m_next);
916 emit_destroy (&(**sp).m_emits);
917 error_destroy (&(**sp).m_errtext);
918 mem_free ((GLvoid **) & (**sp).m_string);
919 mem_free ((GLvoid **) sp);
920 }
921 }
922
923 static GLvoid
924 spec_append (spec ** sp, spec ** ns)
925 {
926 if (*sp)
927 spec_append (&(**sp).m_next, ns);
928 else
929 *sp = *ns;
930 }
931
932 /*
933 * operator typedef
934 */
935 typedef enum oper_
936 {
937 op_none,
938 op_and,
939 op_or
940 } oper;
941
942
943 /*
944 * definition typedef
945 */
946 typedef struct defntn_
947 {
948 oper m_oper;
949 spec *m_specs;
950 struct defntn_ *m_next;
951 #ifndef NDEBUG
952 GLint m_referenced;
953 #endif
954 } defntn;
955
956
957 static GLvoid
958 defntn_create (defntn ** de)
959 {
960 *de = (defntn *) mem_alloc (sizeof (defntn));
961 if (*de) {
962 (**de).m_oper = op_none;
963 (**de).m_specs = NULL;
964 (**de).m_next = NULL;
965 #ifndef NDEBUG
966 (**de).m_referenced = 0;
967 #endif
968 }
969 }
970
971 static GLvoid
972 defntn_destroy (defntn ** de)
973 {
974 if (*de) {
975 defntn_destroy (&(**de).m_next);
976 spec_destroy (&(**de).m_specs);
977 mem_free ((GLvoid **) de);
978 }
979 }
980
981 static GLvoid
982 defntn_append (defntn ** de, defntn ** nd)
983 {
984 if (*de)
985 defntn_append (&(**de).m_next, nd);
986 else
987 *de = *nd;
988 }
989
990 /*
991 * dictionary typedef
992 */
993 typedef struct dict_
994 {
995 defntn *m_defntns;
996 defntn *m_syntax;
997 defntn *m_string;
998 struct dict_ *m_next;
999 } dict;
1000
1001
1002 static GLvoid
1003 dict_create (dict ** di)
1004 {
1005 *di = (dict *) mem_alloc (sizeof (dict));
1006 if (*di) {
1007 (**di).m_defntns = NULL;
1008 (**di).m_syntax = NULL;
1009 (**di).m_string = NULL;
1010 (**di).m_next = NULL;
1011 }
1012 }
1013
1014 static GLvoid
1015 dict_destroy (dict ** di)
1016 {
1017 if (*di) {
1018 dict_destroy (&(**di).m_next);
1019 defntn_destroy (&(**di).m_defntns);
1020 mem_free ((GLvoid **) di);
1021 }
1022 }
1023
1024 /*
1025 * GLubyte array typedef
1026 */
1027 typedef struct barray_
1028 {
1029 GLubyte *data;
1030 GLuint len;
1031 } barray;
1032
1033
1034 static GLvoid
1035 barray_create (barray ** ba)
1036 {
1037 *ba = (barray *) mem_alloc (sizeof (barray));
1038 if (*ba) {
1039 (**ba).data = NULL;
1040 (**ba).len = 0;
1041 }
1042 }
1043
1044 static GLvoid
1045 barray_destroy (barray ** ba)
1046 {
1047 if (*ba) {
1048 mem_free ((GLvoid **) & (**ba).data);
1049 mem_free ((GLvoid **) ba);
1050 }
1051 }
1052
1053 /*
1054 * reallocates GLubyte array to requested size,
1055 * returns 0 on success,
1056 * returns 1 otherwise
1057 */
1058 static GLint
1059 barray_resize (barray ** ba, GLuint nlen)
1060 {
1061 GLubyte *new_pointer;
1062
1063 if (nlen == 0) {
1064 mem_free ((void **) &(**ba).data);
1065 (**ba).data = NULL;
1066 (**ba).len = 0;
1067
1068 return 0;
1069 }
1070 else {
1071 new_pointer = (GLubyte *)
1072 mem_realloc ((**ba).data, (**ba).len * sizeof (GLubyte),
1073 nlen * sizeof (GLubyte));
1074 if (new_pointer) {
1075 (**ba).data = new_pointer;
1076 (**ba).len = nlen;
1077
1078 return 0;
1079 }
1080 }
1081
1082 return 1;
1083 }
1084
1085 /*
1086 * adds GLubyte array pointed by *nb to the end of array pointed by *ba,
1087 * returns 0 on success,
1088 * returns 1 otherwise
1089 */
1090 static GLint
1091 barray_append (barray ** ba, barray ** nb)
1092 {
1093 GLuint i;
1094 const GLuint len = (**ba).len;
1095
1096 if (barray_resize (ba, (**ba).len + (**nb).len))
1097 return 1;
1098
1099 for (i = 0; i < (**nb).len; i++)
1100 (**ba).data[len + i] = (**nb).data[i];
1101
1102 return 0;
1103 }
1104
1105
1106 /**
1107 * Adds emit chain pointed by em to the end of array pointed by *ba.
1108 * \return 0 on success, 1 otherwise.
1109 */
1110 static GLint
1111 barray_push (barray ** ba, emit * em, GLubyte c, GLuint pos)
1112 {
1113 emit *temp = em;
1114 GLuint count = 0;
1115
1116 while (temp) {
1117 if (temp->m_emit_type == et_position)
1118 count += 4; /* position is a 32-bit unsigned integer */
1119 else
1120 count++;
1121
1122 temp = temp->m_next;
1123 }
1124
1125 if (barray_resize (ba, (**ba).len + count))
1126 return 1;
1127
1128 while (em) {
1129 if (em->m_emit_type == et_byte)
1130 (**ba).data[(**ba).len - count--] = em->m_byte;
1131 else if (em->m_emit_type == et_stream)
1132 (**ba).data[(**ba).len - count--] = c;
1133
1134 /* This is where the position is emitted into the stream */
1135 else { /* em->type == et_position */
1136 #if 0
1137 (**ba).data[(**ba).len - count--] = (GLubyte) pos,
1138 (**ba).data[(**ba).len - count--] = (GLubyte) (pos >> 8),
1139 (**ba).data[(**ba).len - count--] = (GLubyte) (pos >> 16),
1140 (**ba).data[(**ba).len - count--] = (GLubyte) (pos >> 24);
1141 #else
1142 (**ba).data[(**ba).len - count--] = (GLubyte) pos;
1143 (**ba).data[(**ba).len - count--] = (GLubyte) (pos / 0x100);
1144 (**ba).data[(**ba).len - count--] = (GLubyte) (pos / 0x10000);
1145 (**ba).data[(**ba).len - count--] = (GLubyte) (pos / 0x1000000);
1146 #endif
1147 }
1148
1149 em = em->m_next;
1150 }
1151
1152 return 0;
1153 }
1154
1155 /**
1156 * string to string map typedef
1157 */
1158 typedef struct map_str_
1159 {
1160 GLubyte *key;
1161 GLubyte *data;
1162 struct map_str_ *next;
1163 } map_str;
1164
1165
1166 static GLvoid
1167 map_str_create (map_str ** ma)
1168 {
1169 *ma = (map_str *) mem_alloc (sizeof (map_str));
1170 if (*ma) {
1171 (**ma).key = NULL;
1172 (**ma).data = NULL;
1173 (**ma).next = NULL;
1174 }
1175 }
1176
1177 static GLvoid
1178 map_str_destroy (map_str ** ma)
1179 {
1180 if (*ma) {
1181 map_str_destroy (&(**ma).next);
1182 mem_free ((GLvoid **) & (**ma).key);
1183 mem_free ((GLvoid **) & (**ma).data);
1184 mem_free ((GLvoid **) ma);
1185 }
1186 }
1187
1188 static GLvoid
1189 map_str_append (map_str ** ma, map_str ** nm)
1190 {
1191 if (*ma)
1192 map_str_append (&(**ma).next, nm);
1193 else
1194 *ma = *nm;
1195 }
1196
1197 /**
1198 * searches the map for specified key,
1199 * if the key is matched, *data is filled with data associated with the key,
1200 * \return 0 if the key is matched, 1 otherwise
1201 */
1202 static GLint
1203 map_str_find (map_str ** ma, const GLubyte * key, GLubyte ** data)
1204 {
1205 while (*ma) {
1206 if (strcmp ((const char *) (**ma).key, (const char *) key) == 0) {
1207 *data = str_duplicate ((**ma).data);
1208 if (*data == NULL)
1209 return 1;
1210
1211 return 0;
1212 }
1213
1214 ma = &(**ma).next;
1215 }
1216
1217 set_last_error (UNRESOLVED_REFERENCE, str_duplicate (key), -1);
1218 return 1;
1219 }
1220
1221 /**
1222 * string to GLubyte map typedef
1223 */
1224 typedef struct map_byte_
1225 {
1226 GLubyte *key;
1227 GLubyte data;
1228 struct map_byte_ *next;
1229 } map_byte;
1230
1231 static GLvoid
1232 map_byte_create (map_byte ** ma)
1233 {
1234 *ma = (map_byte *) mem_alloc (sizeof (map_byte));
1235 if (*ma) {
1236 (**ma).key = NULL;
1237 (**ma).data = 0;
1238 (**ma).next = NULL;
1239 }
1240 }
1241
1242 static GLvoid
1243 map_byte_destroy (map_byte ** ma)
1244 {
1245 if (*ma) {
1246 map_byte_destroy (&(**ma).next);
1247 mem_free ((GLvoid **) & (**ma).key);
1248 mem_free ((GLvoid **) ma);
1249 }
1250 }
1251
1252 static GLvoid
1253 map_byte_append (map_byte ** ma, map_byte ** nm)
1254 {
1255 if (*ma)
1256 map_byte_append (&(**ma).next, nm);
1257 else
1258 *ma = *nm;
1259 }
1260
1261 /**
1262 * Searches the map for specified key,
1263 * If the key is matched, *data is filled with data associated with the key,
1264 * \return 0 if the is matched, 1 otherwise
1265 */
1266 static GLint
1267 map_byte_find (map_byte ** ma, const GLubyte * key, GLubyte * data)
1268 {
1269 while (*ma) {
1270 if (strcmp ((const char *) (**ma).key, (const char *) key) == 0) {
1271 *data = (**ma).data;
1272 return 0;
1273 }
1274
1275 ma = &(**ma).next;
1276 }
1277
1278 set_last_error (UNRESOLVED_REFERENCE, str_duplicate (key), -1);
1279 return 1;
1280 }
1281
1282 /*
1283 * string to defntn map typedef
1284 */
1285 typedef struct map_def_
1286 {
1287 GLubyte *key;
1288 defntn *data;
1289 struct map_def_ *next;
1290 } map_def;
1291
1292 static GLvoid
1293 map_def_create (map_def ** ma)
1294 {
1295 *ma = (map_def *) mem_alloc (sizeof (map_def));
1296 if (*ma) {
1297 (**ma).key = NULL;
1298 (**ma).data = NULL;
1299 (**ma).next = NULL;
1300 }
1301 }
1302
1303 static GLvoid
1304 map_def_destroy (map_def ** ma)
1305 {
1306 if (*ma) {
1307 map_def_destroy (&(**ma).next);
1308 mem_free ((GLvoid **) & (**ma).key);
1309 mem_free ((GLvoid **) ma);
1310 }
1311 }
1312
1313 static GLvoid
1314 map_def_append (map_def ** ma, map_def ** nm)
1315 {
1316 if (*ma)
1317 map_def_append (&(**ma).next, nm);
1318 else
1319 *ma = *nm;
1320 }
1321
1322 /**
1323 * searches the map for specified key,
1324 * if the key is matched, *data is filled with data associated with the key,
1325 * \return 0 if the is matched, 1 otherwise
1326 */
1327 static GLint
1328 map_def_find (map_def ** ma, const GLubyte * key, defntn ** data)
1329 {
1330 while (*ma) {
1331 if (_mesa_strcmp ((const char *) (**ma).key, (const char *) key) == 0) {
1332 *data = (**ma).data;
1333
1334 return 0;
1335 }
1336
1337 ma = &(**ma).next;
1338 }
1339
1340 set_last_error (UNRESOLVED_REFERENCE, str_duplicate (key), -1);
1341 return 1;
1342 }
1343
1344 /*
1345 * returns 1 if given character is a space,
1346 * returns 0 otherwise
1347 */
1348 static GLint
1349 is_space (GLubyte c)
1350 {
1351 return c == ' ' || c == '\t' || c == '\n' || c == '\r';
1352 }
1353
1354 /*
1355 * advances text pointer by 1 if character pointed by *text is a space,
1356 * returns 1 if a space has been eaten,
1357 * returns 0 otherwise
1358 */
1359 static GLint
1360 eat_space (const GLubyte ** text)
1361 {
1362 if (is_space (**text)) {
1363 (*text)++;
1364
1365 return 1;
1366 }
1367
1368 return 0;
1369 }
1370
1371 /*
1372 * returns 1 if text points to C-style comment start string "/ *",
1373 * returns 0 otherwise
1374 */
1375 static GLint
1376 is_comment_start (const GLubyte * text)
1377 {
1378 return text[0] == '/' && text[1] == '*';
1379 }
1380
1381 /*
1382 * advances text pointer to first character after C-style comment block - if any,
1383 * returns 1 if C-style comment block has been encountered and eaten,
1384 * returns 0 otherwise
1385 */
1386 static GLint
1387 eat_comment (const GLubyte ** text)
1388 {
1389 if (is_comment_start (*text)) {
1390 /* *text points to comment block - skip two characters to enter comment body */
1391 *text += 2;
1392 /* skip any character except consecutive '*' and '/' */
1393 while (!((*text)[0] == '*' && (*text)[1] == '/'))
1394 (*text)++;
1395 /* skip those two terminating characters */
1396 *text += 2;
1397
1398 return 1;
1399 }
1400
1401 return 0;
1402 }
1403
1404 /*
1405 * advances text pointer to first character that is neither space nor C-style comment block
1406 */
1407 static GLvoid
1408 eat_spaces (const GLubyte ** text)
1409 {
1410 while (eat_space (text) || eat_comment (text));
1411 }
1412
1413 /*
1414 * resizes string pointed by *ptr to successfully add character c to the end of the string,
1415 * returns 0 on success,
1416 * returns 1 otherwise
1417 */
1418 static GLint
1419 string_grow (GLubyte ** ptr, GLuint * len, GLubyte c)
1420 {
1421 /* reallocate the string in 16-length increments */
1422 if ((*len & 0x0F) == 0x0F || *ptr == NULL) {
1423 GLubyte *tmp = (GLubyte *) mem_realloc (*ptr, (*len) * sizeof (GLubyte),
1424 ((*len + 1 + 1 +
1425 0x0F) & ~0x0F) * sizeof (GLubyte));
1426 if (tmp == NULL)
1427 return 1;
1428
1429 *ptr = tmp;
1430 }
1431
1432 if (c) {
1433 /* append given character */
1434 (*ptr)[*len] = c;
1435 (*len)++;
1436 }
1437 (*ptr)[*len] = '\0';
1438
1439 return 0;
1440 }
1441
1442 /*
1443 * returns 1 if given character is valid identifier character a-z, A-Z, 0-9 or _
1444 * returns 0 otherwise
1445 */
1446 static GLint
1447 is_identifier (GLubyte c)
1448 {
1449 return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
1450 (c >= '0' && c <= '9') || c == '_';
1451 }
1452
1453 /*
1454 * copies characters from *text to *id until non-identifier character is encountered,
1455 * assumes that *id points to NULL object - caller is responsible for later freeing the string,
1456 * text pointer is advanced to point past the copied identifier,
1457 * returns 0 if identifier was successfully copied,
1458 * returns 1 otherwise
1459 */
1460 static GLint
1461 get_identifier (const GLubyte ** text, GLubyte ** id)
1462 {
1463 const GLubyte *t = *text;
1464 GLubyte *p = NULL;
1465 GLuint len = 0;
1466
1467 if (string_grow (&p, &len, '\0'))
1468 return 1;
1469
1470 /* loop while next character in buffer is valid for identifiers */
1471 while (is_identifier (*t)) {
1472 if (string_grow (&p, &len, *t++)) {
1473 mem_free ((GLvoid **) & p);
1474 return 1;
1475 }
1476 }
1477
1478 *text = t;
1479 *id = p;
1480
1481 return 0;
1482 }
1483
1484 /*
1485 * returns 1 if given character is HEX digit 0-9, A-F or a-f,
1486 * returns 0 otherwise
1487 */
1488 static GLint
1489 is_hex (GLubyte c)
1490 {
1491 return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a'
1492 && c <= 'f');
1493 }
1494
1495 /*
1496 * returns value of passed character as if it was HEX digit
1497 */
1498 static GLuint
1499 hex2dec (GLubyte c)
1500 {
1501 if (c >= '0' && c <= '9')
1502 return c - '0';
1503 if (c >= 'A' && c <= 'F')
1504 return c - 'A' + 10;
1505 return c - 'a' + 10;
1506 }
1507
1508 /*
1509 * converts sequence of HEX digits pointed by *text until non-HEX digit is encountered,
1510 * advances text pointer past the converted sequence,
1511 * returns the converted value
1512 */
1513 static GLuint
1514 hex_convert (const GLubyte ** text)
1515 {
1516 GLuint value = 0;
1517
1518 while (is_hex (**text)) {
1519 value = value * 0x10 + hex2dec (**text);
1520 (*text)++;
1521 }
1522
1523 return value;
1524 }
1525
1526 /*
1527 * returns 1 if given character is OCT digit 0-7,
1528 * returns 0 otherwise
1529 */
1530 static GLint
1531 is_oct (GLubyte c)
1532 {
1533 return c >= '0' && c <= '7';
1534 }
1535
1536 /*
1537 * returns value of passed character as if it was OCT digit
1538 */
1539 static GLint
1540 oct2dec (GLubyte c)
1541 {
1542 return c - '0';
1543 }
1544
1545 static GLubyte
1546 get_escape_sequence (const GLubyte ** text)
1547 {
1548 GLint value = 0;
1549
1550 /* skip '\' character */
1551 (*text)++;
1552
1553 switch (*(*text)++) {
1554 case '\'':
1555 return '\'';
1556 case '"':
1557 return '\"';
1558 case '?':
1559 return '\?';
1560 case '\\':
1561 return '\\';
1562 case 'a':
1563 return '\a';
1564 case 'b':
1565 return '\b';
1566 case 'f':
1567 return '\f';
1568 case 'n':
1569 return '\n';
1570 case 'r':
1571 return '\r';
1572 case 't':
1573 return '\t';
1574 case 'v':
1575 return '\v';
1576 case 'x':
1577 return (GLubyte) hex_convert (text);
1578 }
1579
1580 (*text)--;
1581 if (is_oct (**text)) {
1582 value = oct2dec (*(*text)++);
1583 if (is_oct (**text)) {
1584 value = value * 010 + oct2dec (*(*text)++);
1585 if (is_oct (**text))
1586 value = value * 010 + oct2dec (*(*text)++);
1587 }
1588 }
1589
1590 return (GLubyte) value;
1591 }
1592
1593 /*
1594 * copies characters from *text to *str until " or ' character is encountered,
1595 * assumes that *str points to NULL object - caller is responsible for later freeing the string,
1596 * assumes that *text points to " or ' character that starts the string,
1597 * text pointer is advanced to point past the " or ' character,
1598 * returns 0 if string was successfully copied,
1599 * returns 1 otherwise
1600 */
1601 static GLint
1602 get_string (const GLubyte ** text, GLubyte ** str)
1603 {
1604 const GLubyte *t = *text;
1605 GLubyte *p = NULL;
1606 GLuint len = 0;
1607 GLubyte term_char;
1608
1609 if (string_grow (&p, &len, '\0'))
1610 return 1;
1611
1612 /* read " or ' character that starts the string */
1613 term_char = *t++;
1614 /* while next character is not the terminating character */
1615 while (*t && *t != term_char) {
1616 GLubyte c;
1617
1618 if (*t == '\\')
1619 c = get_escape_sequence (&t);
1620 else
1621 c = *t++;
1622
1623 if (string_grow (&p, &len, c)) {
1624 mem_free ((GLvoid **) & p);
1625 return 1;
1626 }
1627 }
1628
1629 /* skip " or ' character that ends the string */
1630 t++;
1631
1632 *text = t;
1633 *str = p;
1634 return 0;
1635 }
1636
1637 /*
1638 * gets emit code, the syntax is: ".emtcode" " " <symbol> " " ("0x" | "0X") <hex_value>
1639 * assumes that *text already points to <symbol>,
1640 * returns 0 if emit code is successfully read,
1641 * returns 1 otherwise
1642 */
1643 static GLint
1644 get_emtcode (const GLubyte ** text, map_byte ** ma)
1645 {
1646 const GLubyte *t = *text;
1647 map_byte *m = NULL;
1648
1649 map_byte_create (&m);
1650 if (m == NULL)
1651 return 1;
1652
1653 if (get_identifier (&t, &m->key)) {
1654 map_byte_destroy (&m);
1655 return 1;
1656 }
1657 eat_spaces (&t);
1658
1659 if (*t == '\'') {
1660 GLubyte *c;
1661
1662 if (get_string (&t, &c)) {
1663 map_byte_destroy (&m);
1664 return 1;
1665 }
1666
1667 m->data = (GLubyte) c[0];
1668 mem_free ((GLvoid **) & c);
1669 }
1670 else {
1671 /* skip HEX "0x" or "0X" prefix */
1672 t += 2;
1673 m->data = (GLubyte) hex_convert (&t);
1674 }
1675
1676 eat_spaces (&t);
1677
1678 *text = t;
1679 *ma = m;
1680 return 0;
1681 }
1682
1683 /*
1684 * returns 0 on success,
1685 * returns 1 otherwise
1686 */
1687 static GLint
1688 get_errtext (const GLubyte ** text, map_str ** ma)
1689 {
1690 const GLubyte *t = *text;
1691 map_str *m = NULL;
1692
1693 map_str_create (&m);
1694 if (m == NULL)
1695 return 1;
1696
1697 if (get_identifier (&t, &m->key)) {
1698 map_str_destroy (&m);
1699 return 1;
1700 }
1701 eat_spaces (&t);
1702
1703 if (get_string (&t, &m->data)) {
1704 map_str_destroy (&m);
1705 return 1;
1706 }
1707 eat_spaces (&t);
1708
1709 *text = t;
1710 *ma = m;
1711 return 0;
1712 }
1713
1714 /*
1715 * returns 0 on success,
1716 * returns 1 otherwise,
1717 */
1718 static GLint
1719 get_error (const GLubyte ** text, error ** er, map_str * maps)
1720 {
1721 const GLubyte *t = *text;
1722 GLubyte *temp = NULL;
1723
1724 if (*t != '.')
1725 return 0;
1726
1727 t++;
1728 if (get_identifier (&t, &temp))
1729 return 1;
1730 eat_spaces (&t);
1731
1732 if (_mesa_strcmp ("error", (char *) temp) != 0) {
1733 mem_free ((GLvoid **) & temp);
1734 return 0;
1735 }
1736
1737 mem_free ((GLvoid **) & temp);
1738
1739 error_create (er);
1740 if (*er == NULL)
1741 return 1;
1742
1743 if (*t == '\"') {
1744 if (get_string (&t, &(**er).m_text)) {
1745 error_destroy (er);
1746 return 1;
1747 }
1748 eat_spaces (&t);
1749 }
1750 else {
1751 if (get_identifier (&t, &temp)) {
1752 error_destroy (er);
1753 return 1;
1754 }
1755 eat_spaces (&t);
1756
1757 if (map_str_find (&maps, temp, &(**er).m_text)) {
1758 mem_free ((GLvoid **) & temp);
1759 error_destroy (er);
1760 return 1;
1761 }
1762
1763 mem_free ((GLvoid **) & temp);
1764 }
1765
1766 /* try to extract "token" from "...$token$..." */
1767 {
1768 char *processed = NULL;
1769 GLuint len = 0, i = 0;
1770
1771 if (string_grow ((GLubyte **) (&processed), &len, '\0')) {
1772 error_destroy (er);
1773 return 1;
1774 }
1775
1776 while (i < _mesa_strlen ((char *) ((**er).m_text))) {
1777 /* check if the dollar sign is repeated - if so skip it */
1778 if ((**er).m_text[i] == '$' && (**er).m_text[i + 1] == '$') {
1779 if (string_grow ((GLubyte **) (&processed), &len, '$')) {
1780 mem_free ((GLvoid **) & processed);
1781 error_destroy (er);
1782 return 1;
1783 }
1784
1785 i += 2;
1786 }
1787 else if ((**er).m_text[i] != '$') {
1788 if (string_grow ((GLubyte **) (&processed), &len, (**er).m_text[i])) {
1789 mem_free ((GLvoid **) & processed);
1790 error_destroy (er);
1791 return 1;
1792 }
1793
1794 i++;
1795 }
1796 else {
1797 if (string_grow ((GLubyte **) (&processed), &len, '$')) {
1798 mem_free ((GLvoid **) & processed);
1799 error_destroy (er);
1800 return 1;
1801 }
1802
1803 {
1804 /* length of token being extracted */
1805 GLuint tlen = 0;
1806
1807 if (string_grow (&(**er).m_token_name, &tlen, '\0')) {
1808 mem_free ((GLvoid **) & processed);
1809 error_destroy (er);
1810 return 1;
1811 }
1812
1813 /* skip the dollar sign */
1814 i++;
1815
1816 while ((**er).m_text[i] != '$') {
1817 if (string_grow
1818 (&(**er).m_token_name, &tlen, (**er).m_text[i])) {
1819 mem_free ((GLvoid **) & processed);
1820 error_destroy (er);
1821 return 1;
1822 }
1823
1824 i++;
1825 }
1826
1827 /* skip the dollar sign */
1828 i++;
1829 }
1830 }
1831 }
1832
1833 mem_free ((GLvoid **) & (**er).m_text);
1834 (**er).m_text = (GLubyte *) processed;
1835 }
1836
1837 *text = t;
1838 return 0;
1839 }
1840
1841 /*
1842 * returns 0 on success,
1843 * returns 1 otherwise,
1844 */
1845 static GLint
1846 get_emits (const GLubyte ** text, emit ** em, map_byte * mapb)
1847 {
1848 const GLubyte *t = *text;
1849 GLubyte *temp = NULL;
1850 emit *e = NULL;
1851
1852 if (*t != '.')
1853 return 0;
1854
1855 t++;
1856 if (get_identifier (&t, &temp))
1857 return 1;
1858 eat_spaces (&t);
1859
1860 /* .emit */
1861 if (_mesa_strcmp ("emit", (char *) temp) != 0) {
1862 mem_free ((GLvoid **) & temp);
1863 return 0;
1864 }
1865
1866 mem_free ((GLvoid **) & temp);
1867
1868 emit_create (&e);
1869 if (e == NULL)
1870 return 1;
1871
1872 /* 0xNN */
1873 if (*t == '0') {
1874 t += 2;
1875 e->m_byte = (GLubyte) hex_convert (&t);
1876
1877 e->m_emit_type = et_byte;
1878 }
1879 /* * */
1880 else if (*t == '*') {
1881 t++;
1882
1883 e->m_emit_type = et_stream;
1884 }
1885 /* $ */
1886 else if (*t == '$') {
1887 t++;
1888
1889 e->m_emit_type = et_position;
1890 }
1891 /* 'c' */
1892 else if (*t == '\'') {
1893 if (get_string (&t, &temp)) {
1894 emit_destroy (&e);
1895 return 1;
1896 }
1897 e->m_byte = (GLubyte) temp[0];
1898
1899 mem_free ((GLvoid **) & temp);
1900
1901 e->m_emit_type = et_byte;
1902 }
1903 else {
1904 if (get_identifier (&t, &temp)) {
1905 emit_destroy (&e);
1906 return 1;
1907 }
1908
1909 if (map_byte_find (&mapb, temp, &e->m_byte)) {
1910 mem_free ((GLvoid **) & temp);
1911 emit_destroy (&e);
1912 return 1;
1913 }
1914
1915 mem_free ((GLvoid **) & temp);
1916
1917 e->m_emit_type = et_byte;
1918 }
1919
1920 eat_spaces (&t);
1921
1922 if (get_emits (&t, &e->m_next, mapb)) {
1923 emit_destroy (&e);
1924 return 1;
1925 }
1926
1927 *text = t;
1928 *em = e;
1929 return 0;
1930 }
1931
1932 /*
1933 * returns 0 on success,
1934 * returns 1 otherwise,
1935 */
1936 static GLint
1937 get_spec (const GLubyte ** text, spec ** sp, map_str * maps, map_byte * mapb)
1938 {
1939 const GLubyte *t = *text;
1940 spec *s = NULL;
1941
1942 spec_create (&s);
1943 if (s == NULL)
1944 return 1;
1945
1946 if (*t == '\'') {
1947 GLubyte *temp = NULL;
1948
1949 if (get_string (&t, &temp)) {
1950 spec_destroy (&s);
1951 return 1;
1952 }
1953 eat_spaces (&t);
1954
1955 if (*t == '-') {
1956 GLubyte *temp2 = NULL;
1957
1958 /* skip the '-' character */
1959 t++;
1960 eat_spaces (&t);
1961
1962 if (get_string (&t, &temp2)) {
1963 mem_free ((GLvoid **) & temp);
1964 spec_destroy (&s);
1965 return 1;
1966 }
1967 eat_spaces (&t);
1968
1969 s->m_spec_type = st_byte_range;
1970 s->m_byte[0] = *temp;
1971 s->m_byte[1] = *temp2;
1972
1973 mem_free ((GLvoid **) & temp2);
1974 }
1975 else {
1976 s->m_spec_type = st_byte;
1977 *s->m_byte = *temp;
1978 }
1979
1980 mem_free ((GLvoid **) & temp);
1981 }
1982 else if (*t == '"') {
1983 if (get_string (&t, &s->m_string)) {
1984 spec_destroy (&s);
1985 return 1;
1986 }
1987 eat_spaces (&t);
1988
1989 s->m_spec_type = st_string;
1990 }
1991 else if (*t == '.') {
1992 GLubyte *keyword = NULL;
1993
1994 /* skip the dot */
1995 t++;
1996
1997 if (get_identifier (&t, &keyword)) {
1998 spec_destroy (&s);
1999 return 1;
2000 }
2001 eat_spaces (&t);
2002
2003 /* .true */
2004 if (_mesa_strcmp ("true", (char *) keyword) == 0) {
2005 s->m_spec_type = st_true;
2006 }
2007 /* .false */
2008 else if (_mesa_strcmp ("false", (char *) keyword) == 0) {
2009 s->m_spec_type = st_false;
2010 }
2011 /* .debug */
2012 else if (_mesa_strcmp ("debug", (char *) keyword) == 0) {
2013 s->m_spec_type = st_debug;
2014 }
2015 /* .loop */
2016 else if (_mesa_strcmp ("loop", (char *) keyword) == 0) {
2017 if (get_identifier (&t, &s->m_string)) {
2018 mem_free ((GLvoid **) & keyword);
2019 spec_destroy (&s);
2020 return 1;
2021 }
2022 eat_spaces (&t);
2023
2024 s->m_spec_type = st_identifier_loop;
2025 }
2026
2027 mem_free ((GLvoid **) & keyword);
2028 }
2029 else {
2030 if (get_identifier (&t, &s->m_string)) {
2031 spec_destroy (&s);
2032 return 1;
2033 }
2034 eat_spaces (&t);
2035
2036 s->m_spec_type = st_identifier;
2037 }
2038
2039 if (get_error (&t, &s->m_errtext, maps)) {
2040 spec_destroy (&s);
2041 return 1;
2042 }
2043
2044 if (get_emits (&t, &s->m_emits, mapb)) {
2045 spec_destroy (&s);
2046 return 1;
2047 }
2048
2049 *text = t;
2050 *sp = s;
2051 return 0;
2052 }
2053
2054 /*
2055 * returns 0 on success,
2056 * returns 1 otherwise,
2057 */
2058 static GLint
2059 get_definition (const GLubyte ** text, defntn ** de, map_str * maps,
2060 map_byte * mapb)
2061 {
2062 const GLubyte *t = *text;
2063 defntn *d = NULL;
2064
2065 defntn_create (&d);
2066 if (d == NULL)
2067 return 1;
2068
2069 if (get_spec (&t, &d->m_specs, maps, mapb)) {
2070 defntn_destroy (&d);
2071 return 1;
2072 }
2073
2074 while (*t != ';') {
2075 GLubyte *op = NULL;
2076 spec *sp = NULL;
2077
2078 /* skip the dot that precedes "and" or "or" */
2079 t++;
2080
2081 /* read "and" or "or" keyword */
2082 if (get_identifier (&t, &op)) {
2083 defntn_destroy (&d);
2084 return 1;
2085 }
2086 eat_spaces (&t);
2087
2088 if (d->m_oper == op_none) {
2089 /* .and */
2090 if (_mesa_strcmp ("and", (char *) op) == 0)
2091 d->m_oper = op_and;
2092 /* .or */
2093 else
2094 d->m_oper = op_or;
2095 }
2096
2097 mem_free ((GLvoid **) & op);
2098
2099 if (get_spec (&t, &sp, maps, mapb)) {
2100 defntn_destroy (&d);
2101 return 1;
2102 }
2103
2104 spec_append (&d->m_specs, &sp);
2105 }
2106
2107 /* skip the semicolon */
2108 t++;
2109 eat_spaces (&t);
2110
2111 *text = t;
2112 *de = d;
2113 return 0;
2114 }
2115
2116 /*
2117 * returns 0 on success,
2118 * returns 1 otherwise,
2119 */
2120 static GLint
2121 update_dependency (map_def * mapd, GLubyte * symbol, defntn ** def)
2122 {
2123 if (map_def_find (&mapd, symbol, def))
2124 return 1;
2125
2126 #ifndef NDEBUG
2127 (**def).m_referenced = 1;
2128 #endif
2129
2130 return 0;
2131 }
2132
2133 /*
2134 * returns 0 on success,
2135 * returns 1 otherwise,
2136 */
2137 static GLint
2138 update_dependencies (dict * di, map_def * mapd, GLubyte ** syntax_symbol,
2139 GLubyte ** string_symbol)
2140 {
2141 defntn *de = di->m_defntns;
2142
2143 if (update_dependency (mapd, *syntax_symbol, &di->m_syntax) ||
2144 (*string_symbol != NULL
2145 && update_dependency (mapd, *string_symbol, &di->m_string)))
2146 return 1;
2147
2148 mem_free ((GLvoid **) syntax_symbol);
2149 mem_free ((GLvoid **) string_symbol);
2150
2151 while (de) {
2152 spec *sp = de->m_specs;
2153
2154 while (sp) {
2155 if (sp->m_spec_type == st_identifier
2156 || sp->m_spec_type == st_identifier_loop) {
2157 if (update_dependency (mapd, sp->m_string, &sp->m_defntn))
2158 return 1;
2159
2160 mem_free ((GLvoid **) & sp->m_string);
2161 }
2162
2163 if (sp->m_errtext && sp->m_errtext->m_token_name) {
2164 if (update_dependency
2165 (mapd, sp->m_errtext->m_token_name, &sp->m_errtext->m_token))
2166 return 1;
2167
2168 mem_free ((GLvoid **) & sp->m_errtext->m_token_name);
2169 }
2170
2171 sp = sp->m_next;
2172 }
2173
2174 de = de->m_next;
2175 }
2176
2177 return 0;
2178 }
2179
2180 typedef enum match_result_
2181 {
2182 mr_not_matched, /* the examined string does not match */
2183 mr_matched, /* the examined string matches */
2184 mr_error_raised, /* mr_not_matched + error has been raised */
2185 mr_dont_emit, /* used by identifier loops only */
2186 mr_internal_error /* an internal error has occured such as out of memory */
2187 } match_result;
2188
2189 static match_result
2190 match (dict * di, const GLubyte * text, GLuint * index, defntn * de,
2191 barray ** ba, GLint filtering_string)
2192 {
2193 GLuint ind = *index;
2194 match_result status = mr_not_matched;
2195 spec *sp = de->m_specs;
2196
2197 /* for every specifier in the definition */
2198 while (sp) {
2199 GLuint i, len, save_ind = ind;
2200 barray *array = NULL;
2201
2202 switch (sp->m_spec_type) {
2203 case st_identifier:
2204 barray_create (&array);
2205 if (array == NULL)
2206 return mr_internal_error;
2207
2208 status =
2209 match (di, text, &ind, sp->m_defntn, &array, filtering_string);
2210 if (status == mr_internal_error) {
2211 barray_destroy (&array);
2212 return mr_internal_error;
2213 }
2214 break;
2215 case st_string:
2216 len = _mesa_strlen ((char *) (sp->m_string));
2217
2218 /* prefilter the stream */
2219 if (!filtering_string && di->m_string) {
2220 barray *ba;
2221 GLuint filter_index = 0;
2222 match_result result;
2223
2224 barray_create (&ba);
2225 if (ba == NULL)
2226 return mr_internal_error;
2227
2228 result =
2229 match (di, text + ind, &filter_index, di->m_string, &ba, 1);
2230
2231 if (result == mr_internal_error) {
2232 barray_destroy (&ba);
2233 return mr_internal_error;
2234 }
2235
2236 if (result != mr_matched) {
2237 barray_destroy (&ba);
2238 status = mr_not_matched;
2239 break;
2240 }
2241
2242 barray_destroy (&ba);
2243
2244 if (filter_index != len
2245 || _mesa_strncmp ((char *)sp->m_string, (char *)(text + ind), len)) {
2246 status = mr_not_matched;
2247 break;
2248 }
2249
2250 status = mr_matched;
2251 ind += len;
2252 }
2253 else {
2254 status = mr_matched;
2255 for (i = 0; status == mr_matched && i < len; i++)
2256 if (text[ind + i] != sp->m_string[i])
2257 status = mr_not_matched;
2258 if (status == mr_matched)
2259 ind += len;
2260 }
2261 break;
2262 case st_byte:
2263 status = text[ind] == *sp->m_byte ? mr_matched : mr_not_matched;
2264 if (status == mr_matched)
2265 ind++;
2266 break;
2267 case st_byte_range:
2268 status = (text[ind] >= sp->m_byte[0]
2269 && text[ind] <=
2270 sp->m_byte[1]) ? mr_matched : mr_not_matched;
2271 if (status == mr_matched)
2272 ind++;
2273 break;
2274 case st_true:
2275 status = mr_matched;
2276 break;
2277 case st_false:
2278 status = mr_not_matched;
2279 break;
2280 case st_debug:
2281 status = mr_matched;
2282 break;
2283 case st_identifier_loop:
2284 barray_create (&array);
2285 if (array == NULL)
2286 return mr_internal_error;
2287
2288 status = mr_dont_emit;
2289 for (;;) {
2290 match_result result;
2291
2292 save_ind = ind;
2293 result =
2294 match (di, text, &ind, sp->m_defntn, &array,
2295 filtering_string);
2296
2297 if (result == mr_error_raised) {
2298 status = result;
2299 break;
2300 }
2301 else if (result == mr_matched) {
2302 if (barray_push (ba, sp->m_emits, text[ind - 1], save_ind)
2303 || barray_append (ba, &array)) {
2304 barray_destroy (&array);
2305 return mr_internal_error;
2306 }
2307 barray_destroy (&array);
2308 barray_create (&array);
2309 if (array == NULL)
2310 return mr_internal_error;
2311 }
2312 else if (result == mr_internal_error) {
2313 barray_destroy (&array);
2314 return mr_internal_error;
2315 }
2316 else
2317 break;
2318 }
2319 break;
2320 };
2321
2322 if (status == mr_error_raised) {
2323 barray_destroy (&array);
2324
2325 return mr_error_raised;
2326 }
2327
2328 if (de->m_oper == op_and && status != mr_matched
2329 && status != mr_dont_emit) {
2330 barray_destroy (&array);
2331
2332 if (sp->m_errtext) {
2333 set_last_error (sp->m_errtext->m_text,
2334 error_get_token (sp->m_errtext, di, text, ind),
2335 ind);
2336
2337 return mr_error_raised;
2338 }
2339
2340 return mr_not_matched;
2341 }
2342
2343 if (status == mr_matched) {
2344 if (sp->m_emits)
2345 if (barray_push (ba, sp->m_emits, text[ind - 1], save_ind)) {
2346 barray_destroy (&array);
2347 return mr_internal_error;
2348 }
2349
2350 if (array)
2351 if (barray_append (ba, &array)) {
2352 barray_destroy (&array);
2353 return mr_internal_error;
2354 }
2355 }
2356
2357 barray_destroy (&array);
2358
2359 if (de->m_oper == op_or
2360 && (status == mr_matched || status == mr_dont_emit)) {
2361 *index = ind;
2362 return mr_matched;
2363 }
2364
2365 sp = sp->m_next;
2366 }
2367
2368 if (de->m_oper == op_and
2369 && (status == mr_matched || status == mr_dont_emit)) {
2370 *index = ind;
2371 return mr_matched;
2372 }
2373
2374 return mr_not_matched;
2375 }
2376
2377 static GLubyte *
2378 error_get_token (error * er, dict * di, const GLubyte * text, unsigned int ind)
2379 {
2380 GLubyte *str = NULL;
2381
2382 if (er->m_token) {
2383 barray *ba;
2384 GLuint filter_index = 0;
2385
2386 barray_create (&ba);
2387 if (ba != NULL) {
2388 if (match (di, text + ind, &filter_index, er->m_token, &ba, 0) ==
2389 mr_matched && filter_index) {
2390 str = (GLubyte *) mem_alloc (filter_index + 1);
2391 if (str != NULL) {
2392 _mesa_strncpy ((char *) str, (char *) (text + ind),
2393 filter_index);
2394 str[filter_index] = '\0';
2395 }
2396 }
2397 barray_destroy (&ba);
2398 }
2399 }
2400
2401 return str;
2402 }
2403
2404 typedef struct grammar_load_state_
2405 {
2406 dict *di;
2407 GLubyte *syntax_symbol;
2408 GLubyte *string_symbol;
2409 map_str *maps;
2410 map_byte *mapb;
2411 map_def *mapd;
2412 } grammar_load_state;
2413
2414
2415 static GLvoid
2416 grammar_load_state_create (grammar_load_state ** gr)
2417 {
2418 *gr = (grammar_load_state *) mem_alloc (sizeof (grammar_load_state));
2419 if (*gr) {
2420 (**gr).di = NULL;
2421 (**gr).syntax_symbol = NULL;
2422 (**gr).string_symbol = NULL;
2423 (**gr).maps = NULL;
2424 (**gr).mapb = NULL;
2425 (**gr).mapd = NULL;
2426 }
2427 }
2428
2429 static GLvoid
2430 grammar_load_state_destroy (grammar_load_state ** gr)
2431 {
2432 if (*gr) {
2433 dict_destroy (&(**gr).di);
2434 mem_free ((GLvoid **) &(**gr).syntax_symbol);
2435 mem_free ((GLvoid **) &(**gr).string_symbol);
2436 map_str_destroy (&(**gr).maps);
2437 map_byte_destroy (&(**gr).mapb);
2438 map_def_destroy (&(**gr).mapd);
2439 mem_free ((GLvoid **) gr);
2440 }
2441 }
2442
2443 /*
2444 * the API
2445 */
2446
2447 /*
2448 * loads grammar script from null-terminated ASCII text
2449 * returns the grammar object
2450 * returns NULL if an error occurs (call grammar_get_last_error to retrieve the error text)
2451 */
2452
2453 static dict *
2454 grammar_load_from_text (const GLubyte * text)
2455 {
2456 dict *d = NULL;
2457 grammar_load_state *g = NULL;
2458
2459 clear_last_error ();
2460
2461 grammar_load_state_create (&g);
2462 if (g == NULL)
2463 return NULL;
2464
2465 dict_create (&g->di);
2466 if (g->di == NULL) {
2467 grammar_load_state_destroy (&g);
2468 return NULL;
2469 }
2470
2471 eat_spaces (&text);
2472
2473 /* skip ".syntax" keyword */
2474 text += 7;
2475 eat_spaces (&text);
2476
2477 /* retrieve root symbol */
2478 if (get_identifier (&text, &g->syntax_symbol)) {
2479 grammar_load_state_destroy (&g);
2480 return NULL;
2481 }
2482 eat_spaces (&text);
2483
2484 /* skip semicolon */
2485 text++;
2486 eat_spaces (&text);
2487
2488 while (*text) {
2489 GLubyte *symbol = NULL;
2490 GLint is_dot = *text == '.';
2491
2492 if (is_dot)
2493 text++;
2494
2495 if (get_identifier (&text, &symbol)) {
2496 grammar_load_state_destroy (&g);
2497 return NULL;
2498 }
2499 eat_spaces (&text);
2500
2501 /* .emtcode */
2502 if (is_dot && _mesa_strcmp ((char *) symbol, "emtcode") == 0) {
2503 map_byte *ma = NULL;
2504
2505 mem_free ((void **) &symbol);
2506
2507 if (get_emtcode (&text, &ma)) {
2508 grammar_load_state_destroy (&g);
2509 return NULL;
2510 }
2511
2512 map_byte_append (&g->mapb, &ma);
2513 }
2514 /* .errtext */
2515 else if (is_dot && _mesa_strcmp ((char *) symbol, "errtext") == 0) {
2516 map_str *ma = NULL;
2517
2518 mem_free ((GLvoid **) &symbol);
2519
2520 if (get_errtext (&text, &ma)) {
2521 grammar_load_state_destroy (&g);
2522 return NULL;
2523 }
2524
2525 map_str_append (&g->maps, &ma);
2526 }
2527 /* .string */
2528 else if (is_dot && _mesa_strcmp ((char *) symbol, "string") == 0) {
2529 mem_free ((GLvoid **) (&symbol));
2530
2531 if (g->di->m_string != NULL) {
2532 grammar_load_state_destroy (&g);
2533 return NULL;
2534 }
2535
2536 if (get_identifier (&text, &g->string_symbol)) {
2537 grammar_load_state_destroy (&g);
2538 return NULL;
2539 }
2540
2541 /* skip semicolon */
2542 eat_spaces (&text);
2543 text++;
2544 eat_spaces (&text);
2545 }
2546 else {
2547 defntn *de = NULL;
2548 map_def *ma = NULL;
2549
2550 if (get_definition (&text, &de, g->maps, g->mapb)) {
2551 grammar_load_state_destroy (&g);
2552 return NULL;
2553 }
2554
2555 defntn_append (&g->di->m_defntns, &de);
2556
2557 /* if definition consist of only one specifier, give it an ".and" operator */
2558 if (de->m_oper == op_none)
2559 de->m_oper = op_and;
2560
2561 map_def_create (&ma);
2562 if (ma == NULL) {
2563 grammar_load_state_destroy (&g);
2564 return NULL;
2565 }
2566
2567 ma->key = symbol;
2568 ma->data = de;
2569 map_def_append (&g->mapd, &ma);
2570 }
2571 }
2572
2573 if (update_dependencies
2574 (g->di, g->mapd, &g->syntax_symbol, &g->string_symbol)) {
2575 grammar_load_state_destroy (&g);
2576 return NULL;
2577 }
2578
2579 d = g->di;
2580 g->di = NULL;
2581
2582 grammar_load_state_destroy (&g);
2583
2584 return d;
2585 }
2586
2587 /**
2588 * checks if a null-terminated text matches given grammar
2589 * returns 0 on error (call grammar_get_last_error to retrieve the error text)
2590 * returns 1 on success, the prod points to newly allocated buffer with
2591 * production and size is filled with the production size
2592 *
2593 * \param id - The grammar returned from grammar_load_from_text()
2594 * \param text - The program string
2595 * \param production - The return parameter for the binary array holding the
2596 * parsed results
2597 * \param size - The return parameter for the size of production
2598 *
2599 * \return 1 on sucess, 0 on parser error
2600 */
2601 static GLint
2602 grammar_check (dict * di, const GLubyte * text, GLubyte ** production,
2603 GLuint *size)
2604 {
2605 barray *ba = NULL;
2606 GLuint index = 0;
2607
2608 clear_last_error ();
2609
2610 barray_create (&ba);
2611 if (ba == NULL)
2612 return 0;
2613
2614 *production = NULL;
2615 *size = 0;
2616
2617 if (match (di, text, &index, di->m_syntax, &ba, 0) != mr_matched) {
2618 barray_destroy (&ba);
2619 return 0;
2620 }
2621
2622 *production = (GLubyte *) mem_alloc (ba->len * sizeof (GLubyte));
2623 if (*production == NULL) {
2624 barray_destroy (&ba);
2625 return 0;
2626 }
2627
2628 memcpy (*production, ba->data, ba->len * sizeof (GLubyte));
2629 *size = ba->len;
2630 barray_destroy (&ba);
2631
2632 return 1;
2633 }
2634
2635 static GLvoid
2636 grammar_get_last_error (GLubyte * text, GLint size, GLint *pos)
2637 {
2638 GLint len = 0, dots_made = 0;
2639 const GLubyte *p = error_message;
2640
2641 *text = '\0';
2642 #define APPEND_CHARACTER(x) if (dots_made == 0) {\
2643 if (len < size - 1) {\
2644 text[len++] = (x); text[len] = '\0';\
2645 } else {\
2646 GLint i;\
2647 for (i = 0; i < 3; i++)\
2648 if (--len >= 0)\
2649 text[len] = '.';\
2650 dots_made = 1;\
2651 }\
2652 }
2653
2654 if (p) {
2655 while (*p) {
2656 if (*p == '$') {
2657 const GLubyte *r = error_param;
2658
2659 while (*r) {
2660 APPEND_CHARACTER (*r)
2661 r++;
2662 }
2663
2664 p++;
2665 }
2666 else {
2667 APPEND_CHARACTER (*p)
2668 p++;
2669 }
2670 }
2671 }
2672 *pos = error_position;
2673 }
2674
2675 /*-----------------------------------------------------------------------
2676 * From here on down is the semantic checking portion
2677 *
2678 */
2679
2680 /**
2681 * Variable Table Handling functions
2682 */
2683 typedef enum
2684 {
2685 vt_none,
2686 vt_address,
2687 vt_attrib,
2688 vt_param,
2689 vt_temp,
2690 vt_output,
2691 vt_alias
2692 } var_type;
2693
2694
2695 /*
2696 * Setting an explicit field for each of the binding properties is a bit wasteful
2697 * of space, but it should be much more clear when reading later on..
2698 */
2699 struct var_cache
2700 {
2701 GLubyte *name;
2702 var_type type;
2703 GLuint address_binding; /* The index of the address register we should
2704 * be using */
2705 GLuint attrib_binding; /* For type vt_attrib, see nvfragprog.h for values */
2706 GLuint attrib_binding_idx; /* The index into the attrib register file corresponding
2707 * to the state in attrib_binding */
2708 GLuint attrib_is_generic; /* If the attrib was specified through a generic
2709 * vertex attrib */
2710 GLuint temp_binding; /* The index of the temp register we are to use */
2711 GLuint output_binding; /* For type vt_output, see nvfragprog.h for values */
2712 GLuint output_binding_idx; /* This is the index into the result register file
2713 * corresponding to the bound result state */
2714 struct var_cache *alias_binding; /* For type vt_alias, points to the var_cache entry
2715 * that this is aliased to */
2716 GLuint param_binding_type; /* {PROGRAM_STATE_VAR, PROGRAM_LOCAL_PARAM,
2717 * PROGRAM_ENV_PARAM} */
2718 GLuint param_binding_begin; /* This is the offset into the program_parameter_list where
2719 * the tokens representing our bound state (or constants)
2720 * start */
2721 GLuint param_binding_length; /* This is how many entries in the the program_parameter_list
2722 * we take up with our state tokens or constants. Note that
2723 * this is _not_ the same as the number of param registers
2724 * we eventually use */
2725 struct var_cache *next;
2726 };
2727
2728 static GLvoid
2729 var_cache_create (struct var_cache **va)
2730 {
2731 *va = (struct var_cache *) _mesa_malloc (sizeof (struct var_cache));
2732 if (*va) {
2733 (**va).name = NULL;
2734 (**va).type = vt_none;
2735 (**va).attrib_binding = ~0;
2736 (**va).attrib_is_generic = 0;
2737 (**va).temp_binding = ~0;
2738 (**va).output_binding = ~0;
2739 (**va).output_binding_idx = ~0;
2740 (**va).param_binding_type = ~0;
2741 (**va).param_binding_begin = ~0;
2742 (**va).param_binding_length = ~0;
2743 (**va).alias_binding = NULL;
2744 (**va).next = NULL;
2745 }
2746 }
2747
2748 static GLvoid
2749 var_cache_destroy (struct var_cache **va)
2750 {
2751 if (*va) {
2752 var_cache_destroy (&(**va).next);
2753 _mesa_free (*va);
2754 *va = NULL;
2755 }
2756 }
2757
2758 static GLvoid
2759 var_cache_append (struct var_cache **va, struct var_cache *nv)
2760 {
2761 if (*va)
2762 var_cache_append (&(**va).next, nv);
2763 else
2764 *va = nv;
2765 }
2766
2767 static struct var_cache *
2768 var_cache_find (struct var_cache *va, GLubyte * name)
2769 {
2770 struct var_cache *first = va;
2771
2772 while (va) {
2773 if (!strcmp ( (const char*) name, (const char*) va->name)) {
2774 if (va->type == vt_alias)
2775 return var_cache_find (first, va->name);
2776 return va;
2777 }
2778
2779 va = va->next;
2780 }
2781
2782 return NULL;
2783 }
2784
2785 /**
2786 * constructs an integer from 4 GLubytes in LE format
2787 */
2788 static GLuint
2789 parse_position (GLubyte ** inst)
2790 {
2791 GLuint value;
2792
2793 value = (GLuint) (*(*inst)++);
2794 value += (GLuint) (*(*inst)++) * 0x100;
2795 value += (GLuint) (*(*inst)++) * 0x10000;
2796 value += (GLuint) (*(*inst)++) * 0x1000000;
2797
2798 return value;
2799 }
2800
2801 /**
2802 * This will, given a string, lookup the string as a variable name in the
2803 * var cache. If the name is found, the var cache node corresponding to the
2804 * var name is returned. If it is not found, a new entry is allocated
2805 *
2806 * \param I Points into the binary array where the string identifier begins
2807 * \param found 1 if the string was found in the var_cache, 0 if it was allocated
2808 * \return The location on the var_cache corresponding the the string starting at I
2809 */
2810 static struct var_cache *
2811 parse_string (GLubyte ** inst, struct var_cache **vc_head,
2812 struct arb_program *Program, GLuint * found)
2813 {
2814 GLubyte *i = *inst;
2815 struct var_cache *va = NULL;
2816
2817 *inst += _mesa_strlen ((char *) i) + 1;
2818
2819 va = var_cache_find (*vc_head, i);
2820
2821 if (va) {
2822 *found = 1;
2823 return va;
2824 }
2825
2826 *found = 0;
2827 var_cache_create (&va);
2828 va->name = i;
2829
2830 var_cache_append (vc_head, va);
2831
2832 return va;
2833 }
2834
2835 static char *
2836 parse_string_without_adding (GLubyte ** inst, struct arb_program *Program)
2837 {
2838 GLubyte *i = *inst;
2839
2840 *inst += _mesa_strlen ((char *) i) + 1;
2841
2842 return (char *) i;
2843 }
2844
2845 /**
2846 * \return 0 if sign is plus, 1 if sign is minus
2847 */
2848 static GLuint
2849 parse_sign (GLubyte ** inst)
2850 {
2851 /*return *(*inst)++ != '+'; */
2852
2853 if (**inst == '-') {
2854 *(*inst)++;
2855 return 1;
2856 }
2857 else if (**inst == '+') {
2858 *(*inst)++;
2859 return 0;
2860 }
2861
2862 return 0;
2863 }
2864
2865 /**
2866 * parses and returns signed integer
2867 */
2868 static GLint
2869 parse_integer (GLubyte ** inst, struct arb_program *Program)
2870 {
2871 GLint sign;
2872 GLint value;
2873
2874 /* check if *inst points to '+' or '-'
2875 * if yes, grab the sign and increment *inst
2876 */
2877 sign = parse_sign (inst);
2878
2879 /* now check if *inst points to 0
2880 * if yes, increment the *inst and return the default value
2881 */
2882 if (**inst == 0) {
2883 *(*inst)++;
2884 return 0;
2885 }
2886
2887 /* parse the integer as you normally would do it */
2888 value = _mesa_atoi (parse_string_without_adding (inst, Program));
2889
2890 /* now, after terminating 0 there is a position
2891 * to parse it - parse_position()
2892 */
2893 Program->Position = parse_position (inst);
2894
2895 if (sign)
2896 value *= -1;
2897
2898 return value;
2899 }
2900
2901 /**
2902 */
2903 static GLfloat
2904 parse_float (GLubyte ** inst, struct arb_program *Program)
2905 {
2906 GLint tmp[5], denom;
2907 GLfloat value = 0;
2908
2909 #if 0
2910 tmp[0] = parse_sign (inst); /* This is the sign of the number + - >0, - -> 1 */
2911 #endif
2912 tmp[1] = parse_integer (inst, Program); /* This is the integer portion of the number */
2913 tmp[2] = parse_integer (inst, Program); /* This is the fractional portion of the number */
2914 tmp[3] = parse_sign (inst); /* This is the sign of the exponent */
2915 tmp[4] = parse_integer (inst, Program); /* This is the exponent */
2916
2917 value = (GLfloat) tmp[1];
2918 denom = 1;
2919 while (denom < tmp[2])
2920 denom *= 10;
2921 value += (GLfloat) tmp[2] / (GLfloat) denom;
2922 #if 0
2923 if (tmp[0])
2924 value *= -1;
2925 #endif
2926 value *= _mesa_pow (10, (GLfloat) tmp[3] * (GLfloat) tmp[4]);
2927
2928 return value;
2929 }
2930
2931 /**
2932 */
2933 static GLfloat
2934 parse_signed_float (GLubyte ** inst, struct arb_program *Program)
2935 {
2936 GLint negate;
2937 GLfloat value;
2938
2939 negate = parse_sign (inst);
2940
2941 value = parse_float (inst, Program);
2942
2943 if (negate)
2944 value *= -1;
2945
2946 return value;
2947 }
2948
2949 /**
2950 * This picks out a constant value from the parsed array. The constant vector is r
2951 * returned in the *values array, which should be of length 4.
2952 *
2953 * \param values - The 4 component vector with the constant value in it
2954 */
2955 static GLvoid
2956 parse_constant (GLubyte ** inst, GLfloat *values, struct arb_program *Program,
2957 GLboolean use)
2958 {
2959 GLuint components, i;
2960
2961
2962 switch (*(*inst)++) {
2963 case CONSTANT_SCALAR:
2964 if (use == GL_TRUE) {
2965 values[0] =
2966 values[1] =
2967 values[2] = values[3] = parse_float (inst, Program);
2968 }
2969 else {
2970 values[0] =
2971 values[1] =
2972 values[2] = values[3] = parse_signed_float (inst, Program);
2973 }
2974
2975 break;
2976 case CONSTANT_VECTOR:
2977 values[0] = values[1] = values[2] = 0;
2978 values[3] = 1;
2979 components = *(*inst)++;
2980 for (i = 0; i < components; i++) {
2981 values[i] = parse_signed_float (inst, Program);
2982 }
2983 break;
2984 }
2985 }
2986
2987
2988 /**
2989 * \param color 0 if color type is primary, 1 if color type is secondary
2990 * \return 0 on sucess, 1 on error
2991 */
2992 static GLuint
2993 parse_color_type (GLcontext * ctx, GLubyte ** inst, struct arb_program *Program,
2994 GLint * color)
2995 {
2996 *color = *(*inst)++ != COLOR_PRIMARY;
2997 return 0;
2998 }
2999
3000 /**
3001 * Get an integer corresponding to a generic vertex attribute.
3002 *
3003 * \return 0 on sucess, 1 on error
3004 */
3005 static GLuint
3006 parse_generic_attrib_num(GLcontext *ctx, GLubyte ** inst,
3007 struct arb_program *Program, GLuint *attrib)
3008 {
3009 *attrib = parse_integer(inst, Program);
3010
3011 if ((*attrib < 0) || (*attrib > MAX_VERTEX_PROGRAM_ATTRIBS))
3012 {
3013 _mesa_set_program_error (ctx, Program->Position,
3014 "Invalid generic vertex attribute index");
3015 _mesa_error (ctx, GL_INVALID_OPERATION, "Invalid generic vertex attribute index");
3016
3017 return 1;
3018 }
3019
3020 return 0;
3021 }
3022
3023
3024 /**
3025 * \param coord The texture unit index
3026 * \return 0 on sucess, 1 on error
3027 */
3028 static GLuint
3029 parse_texcoord_num (GLcontext * ctx, GLubyte ** inst,
3030 struct arb_program *Program, GLuint * coord)
3031 {
3032 *coord = parse_integer (inst, Program);
3033
3034 if ((*coord < 0) || (*coord >= ctx->Const.MaxTextureUnits)) {
3035 _mesa_set_program_error (ctx, Program->Position,
3036 "Invalid texture unit index");
3037 _mesa_error (ctx, GL_INVALID_OPERATION, "Invalid texture unit index");
3038 return 1;
3039 }
3040
3041 Program->TexturesUsed[*coord] = 1;
3042 return 0;
3043 }
3044
3045 /**
3046 * \param coord The weight index
3047 * \return 0 on sucess, 1 on error
3048 */
3049 static GLuint
3050 parse_weight_num (GLcontext * ctx, GLubyte ** inst, struct arb_program *Program,
3051 GLint * coord)
3052 {
3053 *coord = parse_integer (inst, Program);
3054
3055 if ((*coord < 0) || (*coord >= 1)) {
3056 _mesa_set_program_error (ctx, Program->Position,
3057 "Invalid weight index");
3058 _mesa_error (ctx, GL_INVALID_OPERATION, "Invalid weight index");
3059 return 1;
3060 }
3061
3062 return 0;
3063 }
3064
3065 /**
3066 * \param coord The clip plane index
3067 * \return 0 on sucess, 1 on error
3068 */
3069 static GLuint
3070 parse_clipplane_num (GLcontext * ctx, GLubyte ** inst,
3071 struct arb_program *Program, GLint * coord)
3072 {
3073 *coord = parse_integer (inst, Program);
3074
3075 if ((*coord < 0) || (*coord >= (GLint) ctx->Const.MaxClipPlanes)) {
3076 _mesa_set_program_error (ctx, Program->Position,
3077 "Invalid clip plane index");
3078 _mesa_error (ctx, GL_INVALID_OPERATION, "Invalid clip plane index");
3079 return 1;
3080 }
3081
3082 return 0;
3083 }
3084
3085
3086 /**
3087 * \return 0 on front face, 1 on back face
3088 */
3089 static GLuint
3090 parse_face_type (GLubyte ** inst)
3091 {
3092 switch (*(*inst)++) {
3093 case FACE_FRONT:
3094 return 0;
3095
3096 case FACE_BACK:
3097 return 1;
3098 }
3099 return 0;
3100 }
3101
3102
3103 /**
3104 * Given a matrix and a modifier token on the binary array, return tokens
3105 * that _mesa_fetch_state() [program.c] can understand.
3106 *
3107 * \param matrix - the matrix we are talking about
3108 * \param matrix_idx - the index of the matrix we have (for texture & program matricies)
3109 * \param matrix_modifier - the matrix modifier (trans, inv, etc)
3110 * \return 0 on sucess, 1 on failure
3111 */
3112 static GLuint
3113 parse_matrix (GLcontext * ctx, GLubyte ** inst, struct arb_program *Program,
3114 GLint * matrix, GLint * matrix_idx, GLint * matrix_modifier)
3115 {
3116 GLubyte mat = *(*inst)++;
3117
3118 *matrix_idx = 0;
3119
3120 switch (mat) {
3121 case MATRIX_MODELVIEW:
3122 *matrix = STATE_MODELVIEW;
3123 *matrix_idx = parse_integer (inst, Program);
3124 /* XXX: if (*matrix_idx >= ctx->Const. */
3125 break;
3126
3127 case MATRIX_PROJECTION:
3128 *matrix = STATE_PROJECTION;
3129 break;
3130
3131 case MATRIX_MVP:
3132 *matrix = STATE_MVP;
3133 break;
3134
3135 case MATRIX_TEXTURE:
3136 *matrix = STATE_TEXTURE;
3137 *matrix_idx = parse_integer (inst, Program);
3138 if (*matrix_idx >= (GLint) ctx->Const.MaxTextureUnits) {
3139 _mesa_set_program_error (ctx, Program->Position,
3140 "Invalid Texture Unit");
3141 _mesa_error (ctx, GL_INVALID_OPERATION,
3142 "Invalid Texture Unit: %d", *matrix_idx);
3143 return 1;
3144 }
3145 break;
3146
3147 /* XXX: How should we handle the palette matrix? */
3148 case MATRIX_PALETTE:
3149 *matrix_idx = parse_integer (inst, Program);
3150 break;
3151
3152 case MATRIX_PROGRAM:
3153 *matrix = STATE_PROGRAM;
3154 *matrix_idx = parse_integer (inst, Program);
3155 if (*matrix_idx >= (GLint) ctx->Const.MaxProgramMatrices) {
3156 _mesa_set_program_error (ctx, Program->Position,
3157 "Invalid Program Matrix");
3158 _mesa_error (ctx, GL_INVALID_OPERATION,
3159 "Invalid Program Matrix: %d", *matrix_idx);
3160 return 1;
3161 }
3162 break;
3163 }
3164
3165 switch (*(*inst)++) {
3166 case MATRIX_MODIFIER_IDENTITY:
3167 *matrix_modifier = 0;
3168 break;
3169 case MATRIX_MODIFIER_INVERSE:
3170 *matrix_modifier = STATE_MATRIX_INVERSE;
3171 break;
3172 case MATRIX_MODIFIER_TRANSPOSE:
3173 *matrix_modifier = STATE_MATRIX_TRANSPOSE;
3174 break;
3175 case MATRIX_MODIFIER_INVTRANS:
3176 *matrix_modifier = STATE_MATRIX_INVTRANS;
3177 break;
3178 }
3179
3180 return 0;
3181 }
3182
3183
3184 /**
3185 * This parses a state string (rather, the binary version of it) into
3186 * a 6-token sequence as described in _mesa_fetch_state() [program.c]
3187 *
3188 * \param inst - the start in the binary arry to start working from
3189 * \param state_tokens - the storage for the 6-token state description
3190 * \return - 0 on sucess, 1 on error
3191 */
3192 static GLuint
3193 parse_state_single_item (GLcontext * ctx, GLubyte ** inst,
3194 struct arb_program *Program, GLint * state_tokens)
3195 {
3196 switch (*(*inst)++) {
3197 case STATE_MATERIAL_PARSER:
3198 state_tokens[0] = STATE_MATERIAL;
3199 state_tokens[1] = parse_face_type (inst);
3200 switch (*(*inst)++) {
3201 case MATERIAL_AMBIENT:
3202 state_tokens[2] = STATE_AMBIENT;
3203 break;
3204 case MATERIAL_DIFFUSE:
3205 state_tokens[2] = STATE_DIFFUSE;
3206 break;
3207 case MATERIAL_SPECULAR:
3208 state_tokens[2] = STATE_SPECULAR;
3209 break;
3210 case MATERIAL_EMISSION:
3211 state_tokens[2] = STATE_EMISSION;
3212 break;
3213 case MATERIAL_SHININESS:
3214 state_tokens[2] = STATE_SHININESS;
3215 break;
3216 }
3217 break;
3218
3219 case STATE_LIGHT_PARSER:
3220 state_tokens[0] = STATE_LIGHT;
3221 state_tokens[1] = parse_integer (inst, Program);
3222
3223 /* Check the value of state_tokens[1] against the # of lights */
3224 if (state_tokens[1] >= (GLint) ctx->Const.MaxLights) {
3225 _mesa_set_program_error (ctx, Program->Position,
3226 "Invalid Light Number");
3227 _mesa_error (ctx, GL_INVALID_OPERATION,
3228 "Invalid Light Number: %d", state_tokens[1]);
3229 return 1;
3230 }
3231
3232 switch (*(*inst)++) {
3233 case LIGHT_AMBIENT:
3234 state_tokens[2] = STATE_AMBIENT;
3235 break;
3236 case LIGHT_DIFFUSE:
3237 state_tokens[2] = STATE_DIFFUSE;
3238 break;
3239 case LIGHT_SPECULAR:
3240 state_tokens[2] = STATE_SPECULAR;
3241 break;
3242 case LIGHT_POSITION:
3243 state_tokens[2] = STATE_POSITION;
3244 break;
3245 case LIGHT_ATTENUATION:
3246 state_tokens[2] = STATE_ATTENUATION;
3247 break;
3248 case LIGHT_HALF:
3249 state_tokens[2] = STATE_HALF;
3250 break;
3251 case LIGHT_SPOT_DIRECTION:
3252 state_tokens[2] = STATE_SPOT_DIRECTION;
3253 break;
3254 }
3255 break;
3256
3257 case STATE_LIGHT_MODEL:
3258 switch (*(*inst)++) {
3259 case LIGHT_MODEL_AMBIENT:
3260 state_tokens[0] = STATE_LIGHTMODEL_AMBIENT;
3261 break;
3262 case LIGHT_MODEL_SCENECOLOR:
3263 state_tokens[0] = STATE_LIGHTMODEL_SCENECOLOR;
3264 state_tokens[1] = parse_face_type (inst);
3265 break;
3266 }
3267 break;
3268
3269 case STATE_LIGHT_PROD:
3270 state_tokens[0] = STATE_LIGHTPROD;
3271 state_tokens[1] = parse_integer (inst, Program);
3272
3273 /* Check the value of state_tokens[1] against the # of lights */
3274 if (state_tokens[1] >= (GLint) ctx->Const.MaxLights) {
3275 _mesa_set_program_error (ctx, Program->Position,
3276 "Invalid Light Number");
3277 _mesa_error (ctx, GL_INVALID_OPERATION,
3278 "Invalid Light Number: %d", state_tokens[1]);
3279 return 1;
3280 }
3281
3282 state_tokens[2] = parse_face_type (inst);
3283 switch (*(*inst)++) {
3284 case LIGHT_PROD_AMBIENT:
3285 state_tokens[3] = STATE_AMBIENT;
3286 break;
3287 case LIGHT_PROD_DIFFUSE:
3288 state_tokens[3] = STATE_DIFFUSE;
3289 break;
3290 case LIGHT_PROD_SPECULAR:
3291 state_tokens[3] = STATE_SPECULAR;
3292 break;
3293 }
3294 break;
3295
3296
3297 case STATE_FOG:
3298 switch (*(*inst)++) {
3299 case FOG_COLOR:
3300 state_tokens[0] = STATE_FOG_COLOR;
3301 break;
3302 case FOG_PARAMS:
3303 state_tokens[0] = STATE_FOG_PARAMS;
3304 break;
3305 }
3306 break;
3307
3308 case STATE_TEX_ENV:
3309 state_tokens[1] = parse_integer (inst, Program);
3310 switch (*(*inst)++) {
3311 case TEX_ENV_COLOR:
3312 state_tokens[0] = STATE_TEXENV_COLOR;
3313 break;
3314 }
3315 break;
3316
3317 case STATE_TEX_GEN:
3318 {
3319 GLuint type, coord;
3320
3321 state_tokens[0] = STATE_TEXGEN;
3322 /*state_tokens[1] = parse_integer (inst, Program);*/ /* Texture Unit */
3323
3324 if (parse_texcoord_num (ctx, inst, Program, &coord))
3325 return 1;
3326 state_tokens[1] = coord;
3327
3328 /* EYE or OBJECT */
3329 type = *(*inst++);
3330
3331 /* 0 - s, 1 - t, 2 - r, 3 - q */
3332 coord = *(*inst++);
3333
3334 if (type == TEX_GEN_EYE) {
3335 switch (coord) {
3336 case COMPONENT_X:
3337 state_tokens[2] = STATE_TEXGEN_EYE_S;
3338 break;
3339 case COMPONENT_Y:
3340 state_tokens[2] = STATE_TEXGEN_EYE_T;
3341 break;
3342 case COMPONENT_Z:
3343 state_tokens[2] = STATE_TEXGEN_EYE_R;
3344 break;
3345 case COMPONENT_W:
3346 state_tokens[2] = STATE_TEXGEN_EYE_Q;
3347 break;
3348 }
3349 }
3350 else {
3351 switch (coord) {
3352 case COMPONENT_X:
3353 state_tokens[2] = STATE_TEXGEN_OBJECT_S;
3354 break;
3355 case COMPONENT_Y:
3356 state_tokens[2] = STATE_TEXGEN_OBJECT_T;
3357 break;
3358 case COMPONENT_Z:
3359 state_tokens[2] = STATE_TEXGEN_OBJECT_R;
3360 break;
3361 case COMPONENT_W:
3362 state_tokens[2] = STATE_TEXGEN_OBJECT_Q;
3363 break;
3364 }
3365 }
3366 }
3367 break;
3368
3369 case STATE_DEPTH:
3370 switch (*(*inst)++) {
3371 case DEPTH_RANGE:
3372 state_tokens[0] = STATE_DEPTH_RANGE;
3373 break;
3374 }
3375 break;
3376
3377 case STATE_CLIP_PLANE:
3378 state_tokens[0] = STATE_CLIPPLANE;
3379 state_tokens[1] = parse_integer (inst, Program);
3380 if (parse_clipplane_num (ctx, inst, Program, &state_tokens[1]))
3381 return 1;
3382 break;
3383
3384 case STATE_POINT:
3385 switch (*(*inst++)) {
3386 case POINT_SIZE:
3387 state_tokens[0] = STATE_POINT_SIZE;
3388 break;
3389
3390 case POINT_ATTENUATION:
3391 state_tokens[0] = STATE_POINT_ATTENUATION;
3392 break;
3393 }
3394 break;
3395
3396 /* XXX: I think this is the correct format for a matrix row */
3397 case STATE_MATRIX_ROWS:
3398 state_tokens[0] = STATE_MATRIX;
3399
3400 if (parse_matrix
3401 (ctx, inst, Program, &state_tokens[1], &state_tokens[2],
3402 &state_tokens[5]))
3403 return 1;
3404
3405 state_tokens[3] = parse_integer (inst, Program); /* The first row to grab */
3406
3407 state_tokens[4] = parse_integer (inst, Program); /* Either the last row, 0 */
3408 if (state_tokens[4] == 0) {
3409 state_tokens[4] = state_tokens[3];
3410 }
3411 break;
3412 }
3413
3414 return 0;
3415 }
3416
3417 /**
3418 * This parses a state string (rather, the binary version of it) into
3419 * a 6-token similar for the state fetching code in program.c
3420 *
3421 * One might ask, why fetch these parameters into just like you fetch
3422 * state when they are already stored in other places?
3423 *
3424 * Because of array offsets -> We can stick env/local parameters in the
3425 * middle of a parameter array and then index someplace into the array
3426 * when we execute.
3427 *
3428 * One optimization might be to only do this for the cases where the
3429 * env/local parameters end up inside of an array, and leave the
3430 * single parameters (or arrays of pure env/local pareameters) in their
3431 * respective register files.
3432 *
3433 * For ENV parameters, the format is:
3434 * state_tokens[0] = STATE_FRAGMENT_PROGRAM / STATE_VERTEX_PROGRAM
3435 * state_tokens[1] = STATE_ENV
3436 * state_tokens[2] = the parameter index
3437 *
3438 * for LOCAL parameters, the format is:
3439 * state_tokens[0] = STATE_FRAGMENT_PROGRAM / STATE_VERTEX_PROGRAM
3440 * state_tokens[1] = STATE_LOCAL
3441 * state_tokens[2] = the parameter index
3442 *
3443 * \param inst - the start in the binary arry to start working from
3444 * \param state_tokens - the storage for the 6-token state description
3445 * \return - 0 on sucess, 1 on failure
3446 */
3447 static GLuint
3448 parse_program_single_item (GLcontext * ctx, GLubyte ** inst,
3449 struct arb_program *Program, GLint * state_tokens)
3450 {
3451 if (Program->type == GL_FRAGMENT_PROGRAM_ARB)
3452 state_tokens[0] = STATE_FRAGMENT_PROGRAM;
3453 else
3454 state_tokens[0] = STATE_VERTEX_PROGRAM;
3455
3456
3457 switch (*(*inst)++) {
3458 case PROGRAM_PARAM_ENV:
3459 state_tokens[1] = STATE_ENV;
3460 state_tokens[2] = parse_integer (inst, Program);
3461
3462 /* Check state_tokens[2] against the number of ENV parameters available */
3463 if (((Program->type == GL_FRAGMENT_PROGRAM_ARB) &&
3464 (state_tokens[2] >= (GLint) ctx->Const.MaxFragmentProgramEnvParams))
3465 ||
3466 ((Program->type == GL_VERTEX_PROGRAM_ARB) &&
3467 (state_tokens[2] >= (GLint) ctx->Const.MaxVertexProgramEnvParams))) {
3468 _mesa_set_program_error (ctx, Program->Position,
3469 "Invalid Program Env Parameter");
3470 _mesa_error (ctx, GL_INVALID_OPERATION,
3471 "Invalid Program Env Parameter: %d",
3472 state_tokens[2]);
3473 return 1;
3474 }
3475
3476 break;
3477
3478 case PROGRAM_PARAM_LOCAL:
3479 state_tokens[1] = STATE_LOCAL;
3480 state_tokens[2] = parse_integer (inst, Program);
3481
3482 /* Check state_tokens[2] against the number of LOCAL parameters available */
3483 if (((Program->type == GL_FRAGMENT_PROGRAM_ARB) &&
3484 (state_tokens[2] >= (GLint) ctx->Const.MaxFragmentProgramLocalParams))
3485 ||
3486 ((Program->type == GL_VERTEX_PROGRAM_ARB) &&
3487 (state_tokens[2] >= (GLint) ctx->Const.MaxVertexProgramLocalParams))) {
3488 _mesa_set_program_error (ctx, Program->Position,
3489 "Invalid Program Local Parameter");
3490 _mesa_error (ctx, GL_INVALID_OPERATION,
3491 "Invalid Program Local Parameter: %d",
3492 state_tokens[2]);
3493 return 1;
3494 }
3495 break;
3496 }
3497
3498 return 0;
3499 }
3500
3501 /**
3502 * For ARB_vertex_program, programs are not allowed to use both an explicit
3503 * vertex attribute and a generic vertex attribute corresponding to the same
3504 * state. See section 2.14.3.1 of the GL_ARB_vertex_program spec.
3505 *
3506 * This will walk our var_cache and make sure that nobody does anything fishy.
3507 *
3508 * \return 0 on sucess, 1 on error
3509 */
3510 static GLuint
3511 generic_attrib_check(struct var_cache *vc_head)
3512 {
3513 int a;
3514 struct var_cache *curr;
3515 GLboolean explicitAttrib[MAX_VERTEX_PROGRAM_ATTRIBS],
3516 genericAttrib[MAX_VERTEX_PROGRAM_ATTRIBS];
3517
3518 for (a=0; a<MAX_VERTEX_PROGRAM_ATTRIBS; a++) {
3519 explicitAttrib[a] = GL_FALSE;
3520 genericAttrib[a] = GL_FALSE;
3521 }
3522
3523 curr = vc_head;
3524 while (curr) {
3525 if (curr->type == vt_attrib) {
3526 if (curr->attrib_is_generic)
3527 genericAttrib[ curr->attrib_binding_idx ] = GL_TRUE;
3528 else
3529 explicitAttrib[ curr->attrib_binding_idx ] = GL_TRUE;
3530 }
3531
3532 curr = curr->next;
3533 }
3534
3535 for (a=0; a<MAX_VERTEX_PROGRAM_ATTRIBS; a++) {
3536 if ((explicitAttrib[a]) && (genericAttrib[a]))
3537 return 1;
3538 }
3539
3540 return 0;
3541 }
3542
3543 /**
3544 * This will handle the binding side of an ATTRIB var declaration
3545 *
3546 * \param binding - the fragment input register state, defined in nvfragprog.h
3547 * \param binding_idx - the index in the attrib register file that binding is associated with
3548 * \return returns 0 on sucess, 1 on error
3549 *
3550 * See nvfragparse.c for attrib register file layout
3551 */
3552 static GLuint
3553 parse_attrib_binding (GLcontext * ctx, GLubyte ** inst,
3554 struct arb_program *Program, GLuint * binding,
3555 GLuint * binding_idx, GLuint *is_generic)
3556 {
3557 GLuint texcoord;
3558 GLint coord;
3559 GLint err = 0;
3560
3561 *is_generic = 0;
3562 if (Program->type == GL_FRAGMENT_PROGRAM_ARB) {
3563 switch (*(*inst)++) {
3564 case FRAGMENT_ATTRIB_COLOR:
3565 err = parse_color_type (ctx, inst, Program, &coord);
3566 *binding = FRAG_ATTRIB_COL0 + coord;
3567 *binding_idx = 1 + coord;
3568 break;
3569
3570 case FRAGMENT_ATTRIB_TEXCOORD:
3571 err = parse_texcoord_num (ctx, inst, Program, &texcoord);
3572 *binding = FRAG_ATTRIB_TEX0 + texcoord;
3573 *binding_idx = 4 + texcoord;
3574 break;
3575
3576 case FRAGMENT_ATTRIB_FOGCOORD:
3577 *binding = FRAG_ATTRIB_FOGC;
3578 *binding_idx = 3;
3579 break;
3580
3581 case FRAGMENT_ATTRIB_POSITION:
3582 *binding = FRAG_ATTRIB_WPOS;
3583 *binding_idx = 0;
3584 break;
3585
3586 default:
3587 err = 1;
3588 break;
3589 }
3590 }
3591 else {
3592 switch (*(*inst)++) {
3593 case VERTEX_ATTRIB_POSITION:
3594 *binding = VERT_ATTRIB_POS;
3595 *binding_idx = 0;
3596 break;
3597
3598 case VERTEX_ATTRIB_WEIGHT:
3599 {
3600 GLint weight;
3601
3602 err = parse_weight_num (ctx, inst, Program, &weight);
3603 *binding = VERT_ATTRIB_WEIGHT;
3604 *binding_idx = 1;
3605 }
3606 break;
3607
3608 case VERTEX_ATTRIB_NORMAL:
3609 *binding = VERT_ATTRIB_NORMAL;
3610 *binding_idx = 2;
3611 break;
3612
3613 case VERTEX_ATTRIB_COLOR:
3614 {
3615 GLint color;
3616
3617 err = parse_color_type (ctx, inst, Program, &color);
3618 if (color) {
3619 *binding = VERT_ATTRIB_COLOR1;
3620 *binding_idx = 4;
3621 }
3622 else {
3623 *binding = VERT_ATTRIB_COLOR0;
3624 *binding_idx = 3;
3625 }
3626 }
3627 break;
3628
3629 case VERTEX_ATTRIB_FOGCOORD:
3630 *binding = VERT_ATTRIB_FOG;
3631 *binding_idx = 5;
3632 break;
3633
3634 case VERTEX_ATTRIB_TEXCOORD:
3635 {
3636 GLuint unit;
3637
3638 err = parse_texcoord_num (ctx, inst, Program, &unit);
3639 *binding = VERT_ATTRIB_TEX0 + unit;
3640 *binding_idx = 8 + unit;
3641 }
3642 break;
3643
3644 /* XXX: It looks like we don't support this at all, atm */
3645 case VERTEX_ATTRIB_MATRIXINDEX:
3646 parse_integer (inst, Program);
3647 break;
3648
3649 case VERTEX_ATTRIB_GENERIC:
3650 {
3651 GLuint attrib;
3652
3653 if (!parse_generic_attrib_num(ctx, inst, Program, &attrib)) {
3654 *is_generic = 1;
3655 switch (attrib) {
3656 case 0:
3657 *binding = VERT_ATTRIB_POS;
3658 break;
3659 case 1:
3660 *binding = VERT_ATTRIB_WEIGHT;
3661 break;
3662 case 2:
3663 *binding = VERT_ATTRIB_NORMAL;
3664 break;
3665 case 3:
3666 *binding = VERT_ATTRIB_COLOR0;
3667 break;
3668 case 4:
3669 *binding = VERT_ATTRIB_COLOR1;
3670 break;
3671 case 5:
3672 *binding = VERT_ATTRIB_FOG;
3673 break;
3674 case 6:
3675 break;
3676 case 7:
3677 break;
3678 default:
3679 *binding = VERT_ATTRIB_TEX0 + (attrib-8);
3680 break;
3681 }
3682 *binding_idx = attrib;
3683 }
3684 }
3685 break;
3686
3687 default:
3688 err = 1;
3689 break;
3690 }
3691 }
3692
3693 /* Can this even happen? */
3694 if (err) {
3695 _mesa_set_program_error (ctx, Program->Position,
3696 "Bad attribute binding");
3697 _mesa_error (ctx, GL_INVALID_OPERATION, "Bad attribute binding");
3698 }
3699
3700 Program->InputsRead |= (1 << *binding_idx);
3701
3702 return err;
3703 }
3704
3705 /**
3706 * This translates between a binary token for an output variable type
3707 * and the mesa token for the same thing.
3708 *
3709 *
3710 * XXX: What is the 'name' for vertex program state? -> do we need it?
3711 * I don't think we do;
3712 *
3713 * See nvfragprog.h for definitions
3714 *
3715 * \param inst - The parsed tokens
3716 * \param binding - The name of the state we are binding too
3717 * \param binding_idx - The index into the result register file that this is bound too
3718 *
3719 * See nvfragparse.c for the register file layout for fragment programs
3720 * See nvvertparse.c for the register file layout for vertex programs
3721 */
3722 static GLuint
3723 parse_result_binding (GLcontext * ctx, GLubyte ** inst, GLuint * binding,
3724 GLuint * binding_idx, struct arb_program *Program)
3725 {
3726 GLuint b;
3727
3728 switch (*(*inst)++) {
3729 case FRAGMENT_RESULT_COLOR:
3730 /* for frag programs, this is FRAGMENT_RESULT_COLOR */
3731 if (Program->type == GL_FRAGMENT_PROGRAM_ARB) {
3732 *binding = FRAG_OUTPUT_COLR;
3733 *binding_idx = 0;
3734 }
3735 /* for vtx programs, this is VERTEX_RESULT_POSITION */
3736 else {
3737 *binding_idx = 0;
3738 }
3739 break;
3740
3741 case FRAGMENT_RESULT_DEPTH:
3742 /* for frag programs, this is FRAGMENT_RESULT_DEPTH */
3743 if (Program->type == GL_FRAGMENT_PROGRAM_ARB) {
3744 *binding = FRAG_OUTPUT_DEPR;
3745 *binding_idx = 2;
3746 }
3747 /* for vtx programs, this is VERTEX_RESULT_COLOR */
3748 else {
3749 GLint color_type;
3750 GLuint face_type = parse_face_type(inst);
3751 GLint color_type_ret = parse_color_type(ctx, inst, Program, &color_type);
3752
3753 /* back face */
3754 if (face_type) {
3755 if (color_type_ret) return 1;
3756
3757 /* secondary color */
3758 if (color_type) {
3759 *binding_idx = 4;
3760 }
3761 /* primary color */
3762 else {
3763 *binding_idx = 3;
3764 }
3765 }
3766 /* front face */
3767 else {
3768 /* secondary color */
3769 if (color_type) {
3770 *binding_idx = 2;
3771 }
3772 /* primary color */
3773 else {
3774 *binding_idx = 1;
3775 }
3776 }
3777 }
3778 break;
3779
3780 case VERTEX_RESULT_FOGCOORD:
3781 *binding_idx = 5;
3782 break;
3783
3784 case VERTEX_RESULT_POINTSIZE:
3785 *binding_idx = 6;
3786 break;
3787
3788 case VERTEX_RESULT_TEXCOORD:
3789 if (parse_texcoord_num (ctx, inst, Program, &b))
3790 return 1;
3791 *binding_idx = 7 + b;
3792 break;
3793 }
3794
3795 Program->OutputsWritten |= (1 << *binding_idx);
3796
3797 return 0;
3798 }
3799
3800 /**
3801 * This handles the declaration of ATTRIB variables
3802 *
3803 * XXX: Still needs
3804 * parse_vert_attrib_binding(), or something like that
3805 *
3806 * \return 0 on sucess, 1 on error
3807 */
3808 static GLint
3809 parse_attrib (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
3810 struct arb_program *Program)
3811 {
3812 GLuint found;
3813 char *error_msg;
3814 struct var_cache *attrib_var;
3815
3816 attrib_var = parse_string (inst, vc_head, Program, &found);
3817 Program->Position = parse_position (inst);
3818 if (found) {
3819 error_msg = (char *)
3820 _mesa_malloc (_mesa_strlen ((char *) attrib_var->name) + 40);
3821 _mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s",
3822 attrib_var->name);
3823
3824 _mesa_set_program_error (ctx, Program->Position, error_msg);
3825 _mesa_error (ctx, GL_INVALID_OPERATION, error_msg);
3826
3827 _mesa_free (error_msg);
3828 return 1;
3829 }
3830
3831 attrib_var->type = vt_attrib;
3832
3833 /* I think this is ok now - karl */
3834 /* XXX: */
3835 /*if (Program->type == GL_FRAGMENT_PROGRAM_ARB) */
3836 {
3837 if (parse_attrib_binding
3838 (ctx, inst, Program, &attrib_var->attrib_binding,
3839 &attrib_var->attrib_binding_idx, &attrib_var->attrib_is_generic))
3840 return 1;
3841 if (generic_attrib_check(*vc_head)) {
3842 _mesa_set_program_error (ctx, Program->Position,
3843 "Cannot use both a generic vertex attribute and a specific attribute of the same type");
3844 _mesa_error (ctx, GL_INVALID_OPERATION,
3845 "Cannot use both a generic vertex attribute and a specific attribute of the same type");
3846 return 1;
3847 }
3848
3849 }
3850
3851 Program->Base.NumAttributes++;
3852 return 0;
3853 }
3854
3855 /**
3856 * \param use -- TRUE if we're called when declaring implicit parameters,
3857 * FALSE if we're declaraing variables. This has to do with
3858 * if we get a signed or unsigned float for scalar constants
3859 */
3860 static GLuint
3861 parse_param_elements (GLcontext * ctx, GLubyte ** inst,
3862 struct var_cache *param_var,
3863 struct arb_program *Program, GLboolean use)
3864 {
3865 GLint idx;
3866 GLuint err;
3867 GLint state_tokens[6];
3868 GLfloat const_values[4];
3869
3870 err = 0;
3871
3872 switch (*(*inst)++) {
3873 case PARAM_STATE_ELEMENT:
3874
3875 if (parse_state_single_item (ctx, inst, Program, state_tokens))
3876 return 1;
3877
3878 /* If we adding STATE_MATRIX that has multiple rows, we need to
3879 * unroll it and call _mesa_add_state_reference() for each row
3880 */
3881 if ((state_tokens[0] == STATE_MATRIX)
3882 && (state_tokens[3] != state_tokens[4])) {
3883 GLint row;
3884 GLint first_row = state_tokens[3];
3885 GLint last_row = state_tokens[4];
3886
3887 for (row = first_row; row <= last_row; row++) {
3888 state_tokens[3] = state_tokens[4] = row;
3889
3890 idx =
3891 _mesa_add_state_reference (Program->Parameters,
3892 state_tokens);
3893 if (param_var->param_binding_begin == ~0U)
3894 param_var->param_binding_begin = idx;
3895 param_var->param_binding_length++;
3896 Program->Base.NumParameters++;
3897 }
3898 }
3899 else {
3900 idx =
3901 _mesa_add_state_reference (Program->Parameters, state_tokens);
3902 if (param_var->param_binding_begin == ~0U)
3903 param_var->param_binding_begin = idx;
3904 param_var->param_binding_length++;
3905 Program->Base.NumParameters++;
3906 }
3907 break;
3908
3909 case PARAM_PROGRAM_ELEMENT:
3910
3911 if (parse_program_single_item (ctx, inst, Program, state_tokens))
3912 return 1;
3913 idx = _mesa_add_state_reference (Program->Parameters, state_tokens);
3914 if (param_var->param_binding_begin == ~0U)
3915 param_var->param_binding_begin = idx;
3916 param_var->param_binding_length++;
3917 Program->Base.NumParameters++;
3918
3919 /* Check if there is more: 0 -> we're done, else its an integer */
3920 if (**inst) {
3921 GLuint out_of_range, new_idx;
3922 GLuint start_idx = state_tokens[2] + 1;
3923 GLuint end_idx = parse_integer (inst, Program);
3924
3925 out_of_range = 0;
3926 if (Program->type == GL_FRAGMENT_PROGRAM_ARB) {
3927 if (((state_tokens[1] == STATE_ENV)
3928 && (end_idx >= ctx->Const.MaxFragmentProgramEnvParams))
3929 || ((state_tokens[1] == STATE_LOCAL)
3930 && (end_idx >=
3931 ctx->Const.MaxFragmentProgramLocalParams)))
3932 out_of_range = 1;
3933 }
3934 else {
3935 if (((state_tokens[1] == STATE_ENV)
3936 && (end_idx >= ctx->Const.MaxFragmentProgramEnvParams))
3937 || ((state_tokens[1] == STATE_LOCAL)
3938 && (end_idx >=
3939 ctx->Const.MaxFragmentProgramLocalParams)))
3940 out_of_range = 1;
3941 }
3942 if (out_of_range) {
3943 _mesa_set_program_error (ctx, Program->Position,
3944 "Invalid Program Parameter");
3945 _mesa_error (ctx, GL_INVALID_OPERATION,
3946 "Invalid Program Parameter: %d", end_idx);
3947 return 1;
3948 }
3949
3950 for (new_idx = start_idx; new_idx <= end_idx; new_idx++) {
3951 state_tokens[2] = new_idx;
3952 idx =
3953 _mesa_add_state_reference (Program->Parameters,
3954 state_tokens);
3955 param_var->param_binding_length++;
3956 Program->Base.NumParameters++;
3957 }
3958 }
3959 else
3960 {
3961 (*(*inst)++);
3962 }
3963 break;
3964
3965 case PARAM_CONSTANT:
3966 parse_constant (inst, const_values, Program, use);
3967 idx =
3968 _mesa_add_named_constant (Program->Parameters,
3969 (char *) param_var->name, const_values);
3970 if (param_var->param_binding_begin == ~0U)
3971 param_var->param_binding_begin = idx;
3972 param_var->param_binding_length++;
3973 Program->Base.NumParameters++;
3974 break;
3975
3976 default:
3977 _mesa_set_program_error (ctx, Program->Position,
3978 "Unexpected token in parse_param_elements()");
3979 _mesa_error (ctx, GL_INVALID_OPERATION,
3980 "Unexpected token in parse_param_elements()");
3981 return 1;
3982 }
3983
3984 /* Make sure we haven't blown past our parameter limits */
3985 if (((Program->type == GL_VERTEX_PROGRAM_ARB) &&
3986 (Program->Base.NumParameters >=
3987 ctx->Const.MaxVertexProgramLocalParams))
3988 || ((Program->type == GL_FRAGMENT_PROGRAM_ARB)
3989 && (Program->Base.NumParameters >=
3990 ctx->Const.MaxFragmentProgramLocalParams))) {
3991 _mesa_set_program_error (ctx, Program->Position,
3992 "Too many parameter variables");
3993 _mesa_error (ctx, GL_INVALID_OPERATION, "Too many parameter variables");
3994 return 1;
3995 }
3996
3997 return err;
3998 }
3999
4000 /**
4001 * This picks out PARAM program parameter bindings.
4002 *
4003 * XXX: This needs to be stressed & tested
4004 *
4005 * \return 0 on sucess, 1 on error
4006 */
4007 static GLuint
4008 parse_param (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
4009 struct arb_program *Program)
4010 {
4011 GLuint found, specified_length, err;
4012 char *error_msg;
4013 struct var_cache *param_var;
4014
4015 err = 0;
4016 param_var = parse_string (inst, vc_head, Program, &found);
4017 Program->Position = parse_position (inst);
4018
4019 if (found) {
4020 error_msg = (char *) _mesa_malloc (_mesa_strlen ((char *) param_var->name) + 40);
4021 _mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s",
4022 param_var->name);
4023
4024 _mesa_set_program_error (ctx, Program->Position, error_msg);
4025 _mesa_error (ctx, GL_INVALID_OPERATION, error_msg);
4026
4027 _mesa_free (error_msg);
4028 return 1;
4029 }
4030
4031 specified_length = parse_integer (inst, Program);
4032
4033 if (specified_length < 0) {
4034 _mesa_set_program_error (ctx, Program->Position,
4035 "Negative parameter array length");
4036 _mesa_error (ctx, GL_INVALID_OPERATION,
4037 "Negative parameter array length: %d", specified_length);
4038 return 1;
4039 }
4040
4041 param_var->type = vt_param;
4042 param_var->param_binding_length = 0;
4043
4044 /* Right now, everything is shoved into the main state register file.
4045 *
4046 * In the future, it would be nice to leave things ENV/LOCAL params
4047 * in their respective register files, if possible
4048 */
4049 param_var->param_binding_type = PROGRAM_STATE_VAR;
4050
4051 /* Remember to:
4052 * * - add each guy to the parameter list
4053 * * - increment the param_var->param_binding_len
4054 * * - store the param_var->param_binding_begin for the first one
4055 * * - compare the actual len to the specified len at the end
4056 */
4057 while (**inst != PARAM_NULL) {
4058 if (parse_param_elements (ctx, inst, param_var, Program, GL_FALSE))
4059 return 1;
4060 }
4061
4062 /* Test array length here! */
4063 if (specified_length) {
4064 if (specified_length != param_var->param_binding_length) {
4065 _mesa_set_program_error (ctx, Program->Position,
4066 "Declared parameter array lenght does not match parameter list");
4067 _mesa_error (ctx, GL_INVALID_OPERATION,
4068 "Declared parameter array lenght does not match parameter list");
4069 }
4070 }
4071
4072 (*inst)++;
4073
4074 return 0;
4075 }
4076
4077 /**
4078 *
4079 */
4080 static GLuint
4081 parse_param_use (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
4082 struct arb_program *Program, struct var_cache **new_var)
4083 {
4084 struct var_cache *param_var;
4085
4086 /* First, insert a dummy entry into the var_cache */
4087 var_cache_create (&param_var);
4088 param_var->name = (GLubyte *) _mesa_strdup (" ");
4089 param_var->type = vt_param;
4090
4091 param_var->param_binding_length = 0;
4092 /* Don't fill in binding_begin; We use the default value of -1
4093 * to tell if its already initialized, elsewhere.
4094 *
4095 * param_var->param_binding_begin = 0;
4096 */
4097 param_var->param_binding_type = PROGRAM_STATE_VAR;
4098
4099 var_cache_append (vc_head, param_var);
4100
4101 /* Then fill it with juicy parameter goodness */
4102 if (parse_param_elements (ctx, inst, param_var, Program, GL_TRUE))
4103 return 1;
4104
4105 *new_var = param_var;
4106
4107 return 0;
4108 }
4109
4110
4111 /**
4112 * This handles the declaration of TEMP variables
4113 *
4114 * \return 0 on sucess, 1 on error
4115 */
4116 static GLuint
4117 parse_temp (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
4118 struct arb_program *Program)
4119 {
4120 GLuint found;
4121 struct var_cache *temp_var;
4122 char *error_msg;
4123
4124 while (**inst != 0) {
4125 temp_var = parse_string (inst, vc_head, Program, &found);
4126 Program->Position = parse_position (inst);
4127 if (found) {
4128 error_msg = (char *)
4129 _mesa_malloc (_mesa_strlen ((char *) temp_var->name) + 40);
4130 _mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s",
4131 temp_var->name);
4132
4133 _mesa_set_program_error (ctx, Program->Position, error_msg);
4134 _mesa_error (ctx, GL_INVALID_OPERATION, error_msg);
4135
4136 _mesa_free (error_msg);
4137 return 1;
4138 }
4139
4140 temp_var->type = vt_temp;
4141
4142 if (((Program->type == GL_FRAGMENT_PROGRAM_ARB) &&
4143 (Program->Base.NumTemporaries >=
4144 ctx->Const.MaxFragmentProgramTemps))
4145 || ((Program->type == GL_VERTEX_PROGRAM_ARB)
4146 && (Program->Base.NumTemporaries >=
4147 ctx->Const.MaxVertexProgramTemps))) {
4148 _mesa_set_program_error (ctx, Program->Position,
4149 "Too many TEMP variables declared");
4150 _mesa_error (ctx, GL_INVALID_OPERATION,
4151 "Too many TEMP variables declared");
4152 return 1;
4153 }
4154
4155 temp_var->temp_binding = Program->Base.NumTemporaries;
4156 Program->Base.NumTemporaries++;
4157 }
4158 (*inst)++;
4159
4160 return 0;
4161 }
4162
4163 /**
4164 * This handles variables of the OUTPUT variety
4165 *
4166 * \return 0 on sucess, 1 on error
4167 */
4168 static GLuint
4169 parse_output (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
4170 struct arb_program *Program)
4171 {
4172 GLuint found;
4173 struct var_cache *output_var;
4174
4175 output_var = parse_string (inst, vc_head, Program, &found);
4176 Program->Position = parse_position (inst);
4177 if (found) {
4178 char *error_msg;
4179 error_msg = (char *)
4180 _mesa_malloc (_mesa_strlen ((char *) output_var->name) + 40);
4181 _mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s",
4182 output_var->name);
4183
4184 _mesa_set_program_error (ctx, Program->Position, error_msg);
4185 _mesa_error (ctx, GL_INVALID_OPERATION, error_msg);
4186
4187 _mesa_free (error_msg);
4188 return 1;
4189 }
4190
4191 output_var->type = vt_output;
4192 return parse_result_binding (ctx, inst, &output_var->output_binding,
4193 &output_var->output_binding_idx, Program);
4194 }
4195
4196 /**
4197 * This handles variables of the ALIAS kind
4198 *
4199 * \return 0 on sucess, 1 on error
4200 */
4201 static GLuint
4202 parse_alias (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
4203 struct arb_program *Program)
4204 {
4205 GLuint found;
4206 struct var_cache *temp_var;
4207 char *error_msg;
4208
4209
4210 temp_var = parse_string (inst, vc_head, Program, &found);
4211 Program->Position = parse_position (inst);
4212
4213 if (found) {
4214 error_msg = (char *)
4215 _mesa_malloc (_mesa_strlen ((char *) temp_var->name) + 40);
4216 _mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s",
4217 temp_var->name);
4218
4219 _mesa_set_program_error (ctx, Program->Position, error_msg);
4220 _mesa_error (ctx, GL_INVALID_OPERATION, error_msg);
4221
4222 _mesa_free (error_msg);
4223 return 1;
4224 }
4225
4226 temp_var->type = vt_alias;
4227 temp_var->alias_binding = parse_string (inst, vc_head, Program, &found);
4228 Program->Position = parse_position (inst);
4229
4230 if (!found)
4231 {
4232 error_msg = (char *)
4233 _mesa_malloc (_mesa_strlen ((char *) temp_var->name) + 40);
4234 _mesa_sprintf (error_msg, "Alias value %s is not defined",
4235 temp_var->alias_binding->name);
4236
4237 _mesa_set_program_error (ctx, Program->Position, error_msg);
4238 _mesa_error (ctx, GL_INVALID_OPERATION, error_msg);
4239
4240 _mesa_free (error_msg);
4241 return 1;
4242 }
4243
4244 return 0;
4245 }
4246
4247 /**
4248 * This handles variables of the ADDRESS kind
4249 *
4250 * \return 0 on sucess, 1 on error
4251 */
4252 static GLuint
4253 parse_address (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
4254 struct arb_program *Program)
4255 {
4256 GLuint found;
4257 struct var_cache *temp_var;
4258 char *error_msg;
4259
4260 while (**inst != 0) {
4261 temp_var = parse_string (inst, vc_head, Program, &found);
4262 Program->Position = parse_position (inst);
4263 if (found) {
4264 error_msg = (char *)
4265 _mesa_malloc (_mesa_strlen ((char *) temp_var->name) + 40);
4266 _mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s",
4267 temp_var->name);
4268
4269 _mesa_set_program_error (ctx, Program->Position, error_msg);
4270 _mesa_error (ctx, GL_INVALID_OPERATION, error_msg);
4271
4272 _mesa_free (error_msg);
4273 return 1;
4274 }
4275
4276 temp_var->type = vt_address;
4277
4278 if (Program->Base.NumAddressRegs >=
4279 ctx->Const.MaxVertexProgramAddressRegs) {
4280 _mesa_set_program_error (ctx, Program->Position,
4281 "Too many ADDRESS variables declared");
4282 _mesa_error (ctx, GL_INVALID_OPERATION,
4283 "Too many ADDRESS variables declared");
4284 return 1;
4285 }
4286
4287 temp_var->address_binding = Program->Base.NumAddressRegs;
4288 Program->Base.NumAddressRegs++;
4289 }
4290 (*inst)++;
4291
4292 return 0;
4293 }
4294
4295 /**
4296 * Parse a program declaration
4297 *
4298 * \return 0 on sucess, 1 on error
4299 */
4300 static GLint
4301 parse_declaration (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
4302 struct arb_program *Program)
4303 {
4304 GLint err = 0;
4305
4306 switch (*(*inst)++) {
4307 case ADDRESS:
4308 err = parse_address (ctx, inst, vc_head, Program);
4309 break;
4310
4311 case ALIAS:
4312 err = parse_alias (ctx, inst, vc_head, Program);
4313 break;
4314
4315 case ATTRIB:
4316 err = parse_attrib (ctx, inst, vc_head, Program);
4317 break;
4318
4319 case OUTPUT:
4320 err = parse_output (ctx, inst, vc_head, Program);
4321 break;
4322
4323 case PARAM:
4324 err = parse_param (ctx, inst, vc_head, Program);
4325 break;
4326
4327 case TEMP:
4328 err = parse_temp (ctx, inst, vc_head, Program);
4329 break;
4330 }
4331
4332 return err;
4333 }
4334
4335 /**
4336 * Handle the parsing out of a masked destination register
4337 *
4338 * \param File - The register file we write to
4339 * \param Index - The register index we write to
4340 * \param WriteMask - The mask controlling which components we write (1->write)
4341 *
4342 * \return 0 on sucess, 1 on error
4343 */
4344 static GLuint
4345 parse_masked_dst_reg (GLcontext * ctx, GLubyte ** inst,
4346 struct var_cache **vc_head, struct arb_program *Program,
4347 GLint * File, GLint * Index, GLboolean * WriteMask)
4348 {
4349 GLuint result;
4350 GLubyte mask;
4351 struct var_cache *dst;
4352
4353 /* We either have a result register specified, or a
4354 * variable that may or may not be writable
4355 */
4356 switch (*(*inst)++) {
4357 case REGISTER_RESULT:
4358 if (parse_result_binding
4359 (ctx, inst, &result, (GLuint *) Index, Program))
4360 return 1;
4361 *File = PROGRAM_OUTPUT;
4362 break;
4363
4364 case REGISTER_ESTABLISHED_NAME:
4365 dst = parse_string (inst, vc_head, Program, &result);
4366 Program->Position = parse_position (inst);
4367
4368 /* If the name has never been added to our symbol table, we're hosed */
4369 if (!result) {
4370 _mesa_set_program_error (ctx, Program->Position,
4371 "0: Undefined variable");
4372 _mesa_error (ctx, GL_INVALID_OPERATION, "0: Undefined variable: %s",
4373 dst->name);
4374 return 1;
4375 }
4376
4377 switch (dst->type) {
4378 case vt_output:
4379 *File = PROGRAM_OUTPUT;
4380 *Index = dst->output_binding_idx;
4381 break;
4382
4383 case vt_temp:
4384 *File = PROGRAM_TEMPORARY;
4385 *Index = dst->temp_binding;
4386 break;
4387
4388 /* If the var type is not vt_output or vt_temp, no go */
4389 default:
4390 _mesa_set_program_error (ctx, Program->Position,
4391 "Destination register is read only");
4392 _mesa_error (ctx, GL_INVALID_OPERATION,
4393 "Destination register is read only: %s",
4394 dst->name);
4395 return 1;
4396 }
4397 break;
4398
4399 default:
4400 _mesa_set_program_error (ctx, Program->Position,
4401 "Unexpected opcode in parse_masked_dst_reg()");
4402 _mesa_error (ctx, GL_INVALID_OPERATION,
4403 "Unexpected opcode in parse_masked_dst_reg()");
4404 return 1;
4405 }
4406
4407 /* And then the mask.
4408 * w,a -> bit 0
4409 * z,b -> bit 1
4410 * y,g -> bit 2
4411 * x,r -> bit 3
4412 */
4413 mask = *(*inst)++;
4414
4415 WriteMask[0] = (mask & (1 << 3)) >> 3;
4416 WriteMask[1] = (mask & (1 << 2)) >> 2;
4417 WriteMask[2] = (mask & (1 << 1)) >> 1;
4418 WriteMask[3] = (mask & (1));
4419
4420 return 0;
4421 }
4422
4423 /**
4424 * Handle the parsing out of a masked address register
4425 *
4426 * \param Index - The register index we write to
4427 * \param WriteMask - The mask controlling which components we write (1->write)
4428 *
4429 * \return 0 on sucess, 1 on error
4430 */
4431 static GLuint
4432 parse_masked_address_reg (GLcontext * ctx, GLubyte ** inst,
4433 struct var_cache **vc_head,
4434 struct arb_program *Program, GLint * Index,
4435 GLboolean * WriteMask)
4436 {
4437 struct var_cache *dst;
4438 GLuint result;
4439
4440 dst = parse_string (inst, vc_head, Program, &result);
4441 Program->Position = parse_position (inst);
4442
4443 /* If the name has never been added to our symbol table, we're hosed */
4444 if (!result) {
4445 _mesa_set_program_error (ctx, Program->Position, "1: Undefined variable");
4446 _mesa_error (ctx, GL_INVALID_OPERATION, "1: Undefined variable: %s",
4447 dst->name);
4448 return 1;
4449 }
4450
4451 if (dst->type != vt_address) {
4452 _mesa_set_program_error (ctx, Program->Position,
4453 "Variable is not of type ADDRESS");
4454 _mesa_error (ctx, GL_INVALID_OPERATION,
4455 "Variable: %s is not of type ADDRESS", dst->name);
4456 return 1;
4457 }
4458
4459 /* Writemask of .x is implied */
4460 WriteMask[0] = 1;
4461 WriteMask[1] = WriteMask[2] = WriteMask[3] = 0;
4462
4463 return 0;
4464 }
4465
4466 /**
4467 * Parse out a swizzle mask.
4468 *
4469 * The values in the input stream are:
4470 * COMPONENT_X -> x/r
4471 * COMPONENT_Y -> y/g
4472 * COMPONENT_Z-> z/b
4473 * COMPONENT_W-> w/a
4474 *
4475 * The values in the output mask are:
4476 * 0 -> x/r
4477 * 1 -> y/g
4478 * 2 -> z/b
4479 * 3 -> w/a
4480 *
4481 * The len parameter allows us to grab 4 components for a vector
4482 * swizzle, or just 1 component for a scalar src register selection
4483 */
4484 static GLuint
4485 parse_swizzle_mask (GLubyte ** inst, GLubyte * mask, GLint len)
4486 {
4487 GLint a;
4488
4489 for (a = 0; a < 4; a++)
4490 mask[a] = a;
4491
4492 for (a = 0; a < len; a++) {
4493 switch (*(*inst)++) {
4494 case COMPONENT_X:
4495 mask[a] = 0;
4496 break;
4497
4498 case COMPONENT_Y:
4499 mask[a] = 1;
4500 break;
4501
4502 case COMPONENT_Z:
4503 mask[a] = 2;
4504 break;
4505
4506 case COMPONENT_W:
4507 mask[a] = 3;
4508 break;
4509 }
4510 }
4511
4512 return 0;
4513 }
4514
4515 /**
4516 */
4517 static GLuint
4518 parse_extended_swizzle_mask (GLubyte ** inst, GLubyte * mask, GLboolean * Negate)
4519 {
4520 GLint a;
4521 GLubyte swz;
4522
4523 *Negate = GL_FALSE;
4524 for (a = 0; a < 4; a++) {
4525 if (parse_sign (inst))
4526 *Negate = GL_TRUE;
4527
4528 swz = *(*inst)++;
4529
4530 switch (swz) {
4531 case COMPONENT_0:
4532 mask[a] = SWIZZLE_ZERO;
4533 break;
4534 case COMPONENT_1:
4535 mask[a] = SWIZZLE_ONE;
4536 break;
4537 case COMPONENT_X:
4538 mask[a] = 0;
4539 break;
4540 case COMPONENT_Y:
4541 mask[a] = 1;
4542 break;
4543 case COMPONENT_Z:
4544 mask[a] = 2;
4545 break;
4546 case COMPONENT_W:
4547 mask[a] = 3;
4548 break;
4549
4550 }
4551 #if 0
4552 if (swz == 0)
4553 mask[a] = SWIZZLE_ZERO;
4554 else if (swz == 1)
4555 mask[a] = SWIZZLE_ONE;
4556 else
4557 mask[a] = swz - 2;
4558 #endif
4559
4560 }
4561
4562 return 0;
4563 }
4564
4565
4566 static GLuint
4567 parse_src_reg (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
4568 struct arb_program *Program, GLint * File, GLint * Index)
4569 {
4570 struct var_cache *src;
4571 GLuint binding_state, binding_idx, is_generic, found, offset;
4572
4573 /* And the binding for the src */
4574 switch (*(*inst)++) {
4575 case REGISTER_ATTRIB:
4576 if (parse_attrib_binding
4577 (ctx, inst, Program, &binding_state, &binding_idx, &is_generic))
4578 return 1;
4579 *File = PROGRAM_INPUT;
4580 *Index = binding_idx;
4581
4582 /* We need to insert a dummy variable into the var_cache so we can
4583 * catch generic vertex attrib aliasing errors
4584 */
4585 var_cache_create(&src);
4586 src->type = vt_attrib;
4587 src->name = (GLubyte *)_mesa_strdup("Dummy Attrib Variable");
4588 src->attrib_binding = binding_state;
4589 src->attrib_binding_idx = binding_idx;
4590 src->attrib_is_generic = is_generic;
4591 var_cache_append(vc_head, src);
4592 if (generic_attrib_check(*vc_head)) {
4593 _mesa_set_program_error (ctx, Program->Position,
4594 "Cannot use both a generic vertex attribute and a specific attribute of the same type");
4595 _mesa_error (ctx, GL_INVALID_OPERATION,
4596 "Cannot use both a generic vertex attribute and a specific attribute of the same type");
4597 return 1;
4598 }
4599 break;
4600
4601 case REGISTER_PARAM:
4602 switch (**inst) {
4603 case PARAM_ARRAY_ELEMENT:
4604 *(*inst)++;
4605 src = parse_string (inst, vc_head, Program, &found);
4606 Program->Position = parse_position (inst);
4607
4608 if (!found) {
4609 _mesa_set_program_error (ctx, Program->Position,
4610 "2: Undefined variable");
4611 _mesa_error (ctx, GL_INVALID_OPERATION,
4612 "2: Undefined variable: %s", src->name);
4613 return 1;
4614 }
4615
4616 *File = src->param_binding_type;
4617
4618 switch (*(*inst)++) {
4619 case ARRAY_INDEX_ABSOLUTE:
4620 offset = parse_integer (inst, Program);
4621
4622 if ((offset < 0)
4623 || (offset >= src->param_binding_length)) {
4624 _mesa_set_program_error (ctx, Program->Position,
4625 "Index out of range");
4626 _mesa_error (ctx, GL_INVALID_OPERATION,
4627 "Index %d out of range for %s", offset,
4628 src->name);
4629 return 1;
4630 }
4631
4632 *Index = src->param_binding_begin + offset;
4633 break;
4634
4635 /* XXX: */
4636 case ARRAY_INDEX_RELATIVE:
4637 break;
4638 }
4639 break;
4640
4641 default:
4642
4643 if (parse_param_use (ctx, inst, vc_head, Program, &src))
4644 return 1;
4645
4646 *File = src->param_binding_type;
4647 *Index = src->param_binding_begin;
4648 break;
4649 }
4650 break;
4651
4652 case REGISTER_ESTABLISHED_NAME:
4653
4654 src = parse_string (inst, vc_head, Program, &found);
4655 Program->Position = parse_position (inst);
4656
4657 /* If the name has never been added to our symbol table, we're hosed */
4658 if (!found) {
4659 _mesa_set_program_error (ctx, Program->Position,
4660 "3: Undefined variable");
4661 _mesa_error (ctx, GL_INVALID_OPERATION, "3: Undefined variable: %s",
4662 src->name);
4663 return 1;
4664 }
4665
4666 switch (src->type) {
4667 case vt_attrib:
4668 *File = PROGRAM_INPUT;
4669 *Index = src->attrib_binding_idx;
4670 break;
4671
4672 /* XXX: We have to handle offsets someplace in here! -- or are those above? */
4673 case vt_param:
4674 *File = src->param_binding_type;
4675 *Index = src->param_binding_begin;
4676 break;
4677
4678 case vt_temp:
4679 *File = PROGRAM_TEMPORARY;
4680 *Index = src->temp_binding;
4681 break;
4682
4683 /* If the var type is vt_output no go */
4684 default:
4685 _mesa_set_program_error (ctx, Program->Position,
4686 "destination register is read only");
4687 _mesa_error (ctx, GL_INVALID_OPERATION,
4688 "destination register is read only: %s",
4689 src->name);
4690 return 1;
4691 }
4692 break;
4693
4694 default:
4695 _mesa_set_program_error (ctx, Program->Position,
4696 "Unknown token in parse_src_reg");
4697 _mesa_error (ctx, GL_INVALID_OPERATION,
4698 "Unknown token in parse_src_reg");
4699 return 1;
4700 }
4701
4702 return 0;
4703 }
4704
4705 /**
4706 */
4707 static GLuint
4708 parse_vector_src_reg (GLcontext * ctx, GLubyte ** inst,
4709 struct var_cache **vc_head, struct arb_program *Program,
4710 GLint * File, GLint * Index, GLboolean * Negate,
4711 GLubyte * Swizzle)
4712 {
4713 /* Grab the sign */
4714 *Negate = parse_sign (inst);
4715
4716 /* And the src reg */
4717 if (parse_src_reg (ctx, inst, vc_head, Program, File, Index))
4718 return 1;
4719
4720 /* finally, the swizzle */
4721 parse_swizzle_mask (inst, Swizzle, 4);
4722
4723 return 0;
4724 }
4725
4726 /**
4727 */
4728 static GLuint
4729 parse_scalar_src_reg (GLcontext * ctx, GLubyte ** inst,
4730 struct var_cache **vc_head, struct arb_program *Program,
4731 GLint * File, GLint * Index, GLboolean * Negate,
4732 GLubyte * Swizzle)
4733 {
4734 /* Grab the sign */
4735 *Negate = parse_sign (inst);
4736
4737 /* And the src reg */
4738 if (parse_src_reg (ctx, inst, vc_head, Program, File, Index))
4739 return 1;
4740
4741 /* Now, get the component and shove it into all the swizzle slots */
4742 parse_swizzle_mask (inst, Swizzle, 1);
4743
4744 return 0;
4745 }
4746
4747 /**
4748 * This is a big mother that handles getting opcodes into the instruction
4749 * and handling the src & dst registers for fragment program instructions
4750 */
4751 static GLuint
4752 parse_fp_instruction (GLcontext * ctx, GLubyte ** inst,
4753 struct var_cache **vc_head, struct arb_program *Program,
4754 struct fp_instruction *fp)
4755 {
4756 GLint a, b;
4757 GLubyte swz[4]; /* FP's swizzle mask is a GLubyte, while VP's is GLuint */
4758 GLuint texcoord;
4759 GLubyte instClass, type, code;
4760
4761 /* No condition codes in ARB_fp */
4762 fp->UpdateCondRegister = 0;
4763
4764 /* Record the position in the program string for debugging */
4765 fp->StringPos = Program->Position;
4766
4767 /* F_ALU_INST or F_TEX_INST */
4768 instClass = *(*inst)++;
4769
4770 /* F_ALU_{VECTOR, SCALAR, BINSC, BIN, TRI, SWZ},
4771 * F_TEX_{SAMPLE, KIL}
4772 */
4773 type = *(*inst)++;
4774
4775 /* The actual opcode name */
4776 code = *(*inst)++;
4777
4778 /* Increment the correct count */
4779 switch (instClass) {
4780 case F_ALU_INST:
4781 Program->NumAluInstructions++;
4782 break;
4783 case F_TEX_INST:
4784 Program->NumTexInstructions++;
4785 break;
4786 }
4787
4788 fp->Saturate = 0;
4789 fp->Precision = FLOAT32;
4790
4791 fp->DstReg.CondMask = COND_TR;
4792
4793 switch (type) {
4794 case F_ALU_VECTOR:
4795 switch (code) {
4796 case F_ABS_SAT:
4797 fp->Saturate = 1;
4798 case F_ABS:
4799 fp->Opcode = FP_OPCODE_ABS;
4800 break;
4801
4802 case F_FLR_SAT:
4803 fp->Saturate = 1;
4804 case F_FLR:
4805 fp->Opcode = FP_OPCODE_FLR;
4806 break;
4807
4808 case F_FRC_SAT:
4809 fp->Saturate = 1;
4810 case F_FRC:
4811 fp->Opcode = FP_OPCODE_FRC;
4812 break;
4813
4814 case F_LIT_SAT:
4815 fp->Saturate = 1;
4816 case F_LIT:
4817 fp->Opcode = FP_OPCODE_LIT;
4818 break;
4819
4820 case F_MOV_SAT:
4821 fp->Saturate = 1;
4822 case F_MOV:
4823 fp->Opcode = FP_OPCODE_MOV;
4824 break;
4825 }
4826
4827 if (parse_masked_dst_reg
4828 (ctx, inst, vc_head, Program, (GLint *) & fp->DstReg.File,
4829 &fp->DstReg.Index, fp->DstReg.WriteMask))
4830 return 1;
4831
4832 fp->SrcReg[0].Abs = GL_FALSE;
4833 fp->SrcReg[0].NegateAbs = GL_FALSE;
4834 if (parse_vector_src_reg
4835 (ctx, inst, vc_head, Program, (GLint *) & fp->SrcReg[0].File,
4836 &fp->SrcReg[0].Index, &fp->SrcReg[0].NegateBase,
4837 swz))
4838 return 1;
4839 for (b=0; b<4; b++)
4840 fp->SrcReg[0].Swizzle[b] = swz[b];
4841 break;
4842
4843 case F_ALU_SCALAR:
4844 switch (code) {
4845 case F_COS_SAT:
4846 fp->Saturate = 1;
4847 case F_COS:
4848 fp->Opcode = FP_OPCODE_COS;
4849 break;
4850
4851 case F_EX2_SAT:
4852 fp->Saturate = 1;
4853 case F_EX2:
4854 fp->Opcode = FP_OPCODE_EX2;
4855 break;
4856
4857 case F_LG2_SAT:
4858 fp->Saturate = 1;
4859 case F_LG2:
4860 fp->Opcode = FP_OPCODE_LG2;
4861 break;
4862
4863 case F_RCP_SAT:
4864 fp->Saturate = 1;
4865 case F_RCP:
4866 fp->Opcode = FP_OPCODE_RCP;
4867 break;
4868
4869 case F_RSQ_SAT:
4870 fp->Saturate = 1;
4871 case F_RSQ:
4872 fp->Opcode = FP_OPCODE_RSQ;
4873 break;
4874
4875 case F_SIN_SAT:
4876 fp->Saturate = 1;
4877 case F_SIN:
4878 fp->Opcode = FP_OPCODE_SIN;
4879 break;
4880
4881 case F_SCS_SAT:
4882 fp->Saturate = 1;
4883 case F_SCS:
4884 fp->Opcode = FP_OPCODE_SCS;
4885 break;
4886 }
4887
4888 if (parse_masked_dst_reg
4889 (ctx, inst, vc_head, Program, (GLint *) & fp->DstReg.File,
4890 &fp->DstReg.Index, fp->DstReg.WriteMask))
4891 return 1;
4892 fp->SrcReg[0].Abs = GL_FALSE;
4893 fp->SrcReg[0].NegateAbs = GL_FALSE;
4894 if (parse_scalar_src_reg
4895 (ctx, inst, vc_head, Program, (GLint *) & fp->SrcReg[0].File,
4896 &fp->SrcReg[0].Index, &fp->SrcReg[0].NegateBase,
4897 swz))
4898 return 1;
4899 for (b=0; b<4; b++)
4900 fp->SrcReg[0].Swizzle[b] = swz[b];
4901 break;
4902
4903 case F_ALU_BINSC:
4904 switch (code) {
4905 case F_POW_SAT:
4906 fp->Saturate = 1;
4907 case F_POW:
4908 fp->Opcode = FP_OPCODE_POW;
4909 break;
4910 }
4911
4912 if (parse_masked_dst_reg
4913 (ctx, inst, vc_head, Program, (GLint *) & fp->DstReg.File,
4914 &fp->DstReg.Index, fp->DstReg.WriteMask))
4915 return 1;
4916 for (a = 0; a < 2; a++) {
4917 fp->SrcReg[a].Abs = GL_FALSE;
4918 fp->SrcReg[a].NegateAbs = GL_FALSE;
4919 if (parse_scalar_src_reg
4920 (ctx, inst, vc_head, Program, (GLint *) & fp->SrcReg[a].File,
4921 &fp->SrcReg[a].Index, &fp->SrcReg[a].NegateBase,
4922 swz))
4923 return 1;
4924 for (b=0; b<4; b++)
4925 fp->SrcReg[a].Swizzle[b] = swz[b];
4926 }
4927 break;
4928
4929
4930 case F_ALU_BIN:
4931 switch (code) {
4932 case F_ADD_SAT:
4933 fp->Saturate = 1;
4934 case F_ADD:
4935 fp->Opcode = FP_OPCODE_ADD;
4936 break;
4937
4938 case F_DP3_SAT:
4939 fp->Saturate = 1;
4940 case F_DP3:
4941 fp->Opcode = FP_OPCODE_DP3;
4942 break;
4943
4944 case F_DP4_SAT:
4945 fp->Saturate = 1;
4946 case F_DP4:
4947 fp->Opcode = FP_OPCODE_DP4;
4948 break;
4949
4950 case F_DPH_SAT:
4951 fp->Saturate = 1;
4952 case F_DPH:
4953 fp->Opcode = FP_OPCODE_DPH;
4954 break;
4955
4956 case F_DST_SAT:
4957 fp->Saturate = 1;
4958 case F_DST:
4959 fp->Opcode = FP_OPCODE_DST;
4960 break;
4961
4962 case F_MAX_SAT:
4963 fp->Saturate = 1;
4964 case F_MAX:
4965 fp->Opcode = FP_OPCODE_MAX;
4966 break;
4967
4968 case F_MIN_SAT:
4969 fp->Saturate = 1;
4970 case F_MIN:
4971 fp->Opcode = FP_OPCODE_MIN;
4972 break;
4973
4974 case F_MUL_SAT:
4975 fp->Saturate = 1;
4976 case F_MUL:
4977 fp->Opcode = FP_OPCODE_MUL;
4978 break;
4979
4980 case F_SGE_SAT:
4981 fp->Saturate = 1;
4982 case F_SGE:
4983 fp->Opcode = FP_OPCODE_SGE;
4984 break;
4985
4986 case F_SLT_SAT:
4987 fp->Saturate = 1;
4988 case F_SLT:
4989 fp->Opcode = FP_OPCODE_SLT;
4990 break;
4991
4992 case F_SUB_SAT:
4993 fp->Saturate = 1;
4994 case F_SUB:
4995 fp->Opcode = FP_OPCODE_SUB;
4996 break;
4997
4998 case F_XPD_SAT:
4999 fp->Saturate = 1;
5000 case F_XPD:
5001 fp->Opcode = FP_OPCODE_X2D;
5002 break;
5003 }
5004
5005 if (parse_masked_dst_reg
5006 (ctx, inst, vc_head, Program, (GLint *) & fp->DstReg.File,
5007 &fp->DstReg.Index, fp->DstReg.WriteMask))
5008 return 1;
5009 for (a = 0; a < 2; a++) {
5010 fp->SrcReg[a].Abs = GL_FALSE;
5011 fp->SrcReg[a].NegateAbs = GL_FALSE;
5012 if (parse_vector_src_reg
5013 (ctx, inst, vc_head, Program, (GLint *) & fp->SrcReg[a].File,
5014 &fp->SrcReg[a].Index, &fp->SrcReg[a].NegateBase,
5015 swz))
5016 return 1;
5017 for (b=0; b<4; b++)
5018 fp->SrcReg[a].Swizzle[b] = swz[b];
5019 }
5020 break;
5021
5022 case F_ALU_TRI:
5023 switch (code) {
5024 case F_CMP_SAT:
5025 fp->Saturate = 1;
5026 case F_CMP:
5027 fp->Opcode = FP_OPCODE_CMP;
5028 break;
5029
5030 case F_LRP_SAT:
5031 fp->Saturate = 1;
5032 case F_LRP:
5033 fp->Opcode = FP_OPCODE_LRP;
5034 break;
5035
5036 case F_MAD_SAT:
5037 fp->Saturate = 1;
5038 case F_MAD:
5039 fp->Opcode = FP_OPCODE_MAD;
5040 break;
5041 }
5042
5043 if (parse_masked_dst_reg
5044 (ctx, inst, vc_head, Program, (GLint *) & fp->DstReg.File,
5045 &fp->DstReg.Index, fp->DstReg.WriteMask))
5046 return 1;
5047 for (a = 0; a < 3; a++) {
5048 fp->SrcReg[a].Abs = GL_FALSE;
5049 fp->SrcReg[a].NegateAbs = GL_FALSE;
5050 if (parse_vector_src_reg
5051 (ctx, inst, vc_head, Program, (GLint *) & fp->SrcReg[a].File,
5052 &fp->SrcReg[a].Index, &fp->SrcReg[a].NegateBase,
5053 swz))
5054 return 1;
5055 for (b=0; b<4; b++)
5056 fp->SrcReg[a].Swizzle[b] = swz[b];
5057 }
5058 break;
5059
5060 case F_ALU_SWZ:
5061 switch (code) {
5062 case F_SWZ_SAT:
5063 fp->Saturate = 1;
5064 case F_SWZ:
5065 fp->Opcode = FP_OPCODE_SWZ;
5066 break;
5067 }
5068 if (parse_masked_dst_reg
5069 (ctx, inst, vc_head, Program, (GLint *) & fp->DstReg.File,
5070 &fp->DstReg.Index, fp->DstReg.WriteMask))
5071 return 1;
5072
5073 if (parse_src_reg
5074 (ctx, inst, vc_head, Program, (GLint *) & fp->SrcReg[0].File,
5075 &fp->SrcReg[0].Index))
5076 return 1;
5077 parse_extended_swizzle_mask (inst, swz,
5078 &fp->SrcReg[0].NegateBase);
5079 for (b=0; b<4; b++)
5080 fp->SrcReg[0].Swizzle[b] = swz[b];
5081 break;
5082
5083 case F_TEX_SAMPLE:
5084 switch (code) {
5085 case F_TEX_SAT:
5086 fp->Saturate = 1;
5087 case F_TEX:
5088 fp->Opcode = FP_OPCODE_TEX;
5089 break;
5090
5091 case F_TXP_SAT:
5092 fp->Saturate = 1;
5093 case F_TXP:
5094 fp->Opcode = FP_OPCODE_TXP;
5095 break;
5096
5097 case F_TXB_SAT:
5098 fp->Saturate = 1;
5099 case F_TXB:
5100 fp->Opcode = FP_OPCODE_TXB;
5101 break;
5102 }
5103
5104 if (parse_masked_dst_reg
5105 (ctx, inst, vc_head, Program, (GLint *) & fp->DstReg.File,
5106 &fp->DstReg.Index, fp->DstReg.WriteMask))
5107 return 1;
5108 fp->SrcReg[0].Abs = GL_FALSE;
5109 fp->SrcReg[0].NegateAbs = GL_FALSE;
5110 if (parse_vector_src_reg
5111 (ctx, inst, vc_head, Program, (GLint *) & fp->SrcReg[0].File,
5112 &fp->SrcReg[0].Index, &fp->SrcReg[0].NegateBase,
5113 swz))
5114 return 1;
5115 for (b=0; b<4; b++)
5116 fp->SrcReg[0].Swizzle[b] = swz[b];
5117
5118 /* texImageUnit */
5119 if (parse_texcoord_num (ctx, inst, Program, &texcoord))
5120 return 1;
5121 fp->TexSrcUnit = texcoord;
5122
5123 /* texTarget */
5124 switch (*(*inst)++) {
5125 case TEXTARGET_1D:
5126 fp->TexSrcBit = TEXTURE_1D_BIT;
5127 break;
5128 case TEXTARGET_2D:
5129 fp->TexSrcBit = TEXTURE_2D_BIT;
5130 break;
5131 case TEXTARGET_3D:
5132 fp->TexSrcBit = TEXTURE_3D_BIT;
5133 break;
5134 case TEXTARGET_RECT:
5135 fp->TexSrcBit = TEXTURE_RECT_BIT;
5136 break;
5137 case TEXTARGET_CUBE:
5138 fp->TexSrcBit = TEXTURE_CUBE_BIT;
5139 break;
5140 }
5141 break;
5142
5143 case F_TEX_KIL:
5144 fp->Opcode = FP_OPCODE_KIL;
5145 fp->SrcReg[0].Abs = GL_FALSE;
5146 fp->SrcReg[0].NegateAbs = GL_FALSE;
5147 if (parse_vector_src_reg
5148 (ctx, inst, vc_head, Program, (GLint *) & fp->SrcReg[0].File,
5149 &fp->SrcReg[0].Index, &fp->SrcReg[0].NegateBase,
5150 swz))
5151 return 1;
5152 for (b=0; b<4; b++)
5153 fp->SrcReg[0].Swizzle[b] = swz[b];
5154 break;
5155 }
5156
5157 return 0;
5158 }
5159
5160 /**
5161 * This is a big mother that handles getting opcodes into the instruction
5162 * and handling the src & dst registers for vertex program instructions
5163 */
5164 static GLuint
5165 parse_vp_instruction (GLcontext * ctx, GLubyte ** inst,
5166 struct var_cache **vc_head, struct arb_program *Program,
5167 struct vp_instruction *vp)
5168 {
5169 GLint a;
5170 GLubyte type, code;
5171
5172 /* V_GEN_{ARL, VECTOR, SCALAR, BINSC, BIN, TRI, SWZ} */
5173 type = *(*inst)++;
5174
5175 /* The actual opcode name */
5176 code = *(*inst)++;
5177
5178 vp->SrcReg[0].RelAddr = vp->SrcReg[1].RelAddr = vp->SrcReg[2].RelAddr = 0;
5179
5180 for (a = 0; a < 4; a++) {
5181 vp->SrcReg[0].Swizzle[a] = a;
5182 vp->SrcReg[1].Swizzle[a] = a;
5183 vp->SrcReg[2].Swizzle[a] = a;
5184 vp->DstReg.WriteMask[a] = 1;
5185 }
5186
5187 switch (type) {
5188 /* XXX: */
5189 case V_GEN_ARL:
5190 vp->Opcode = VP_OPCODE_ARL;
5191
5192 /* Remember to set SrcReg.RelAddr; */
5193
5194 /* Get the masked address register [dst] */
5195 if (parse_masked_address_reg
5196 (ctx, inst, vc_head, Program, &vp->DstReg.Index,
5197 vp->DstReg.WriteMask))
5198 return 1;
5199 vp->DstReg.File = PROGRAM_ADDRESS;
5200
5201
5202 /* Get a scalar src register */
5203 if (parse_scalar_src_reg
5204 (ctx, inst, vc_head, Program, (GLint *) & vp->SrcReg[0].File,
5205 &vp->SrcReg[0].Index, &vp->SrcReg[0].Negate,
5206 vp->SrcReg[0].Swizzle))
5207 return 1;
5208
5209 break;
5210
5211 case V_GEN_VECTOR:
5212 switch (code) {
5213 case V_ABS:
5214 vp->Opcode = VP_OPCODE_ABS;
5215 break;
5216 case V_FLR:
5217 vp->Opcode = VP_OPCODE_FLR;
5218 break;
5219 case V_FRC:
5220 vp->Opcode = VP_OPCODE_FRC;
5221 break;
5222 case V_LIT:
5223 vp->Opcode = VP_OPCODE_LIT;
5224 break;
5225 case V_MOV:
5226 vp->Opcode = VP_OPCODE_MOV;
5227 break;
5228 }
5229 if (parse_masked_dst_reg
5230 (ctx, inst, vc_head, Program, (GLint *) & vp->DstReg.File,
5231 &vp->DstReg.Index, vp->DstReg.WriteMask))
5232 return 1;
5233 if (parse_vector_src_reg
5234 (ctx, inst, vc_head, Program, (GLint *) & vp->SrcReg[0].File,
5235 &vp->SrcReg[0].Index, &vp->SrcReg[0].Negate,
5236 vp->SrcReg[0].Swizzle))
5237 return 1;
5238 break;
5239
5240 case V_GEN_SCALAR:
5241 switch (code) {
5242 case V_EX2:
5243 vp->Opcode = VP_OPCODE_EX2;
5244 break;
5245 case V_EXP:
5246 vp->Opcode = VP_OPCODE_EXP;
5247 break;
5248 case V_LG2:
5249 vp->Opcode = VP_OPCODE_LG2;
5250 break;
5251 case V_LOG:
5252 vp->Opcode = VP_OPCODE_LOG;
5253 break;
5254 case V_RCP:
5255 vp->Opcode = VP_OPCODE_RCP;
5256 break;
5257 case V_RSQ:
5258 vp->Opcode = VP_OPCODE_RSQ;
5259 break;
5260 }
5261 if (parse_masked_dst_reg
5262 (ctx, inst, vc_head, Program, (GLint *) & vp->DstReg.File,
5263 &vp->DstReg.Index, vp->DstReg.WriteMask))
5264 return 1;
5265 if (parse_scalar_src_reg
5266 (ctx, inst, vc_head, Program, (GLint *) & vp->SrcReg[0].File,
5267 &vp->SrcReg[0].Index, &vp->SrcReg[0].Negate,
5268 vp->SrcReg[0].Swizzle))
5269 return 1;
5270 break;
5271
5272 case V_GEN_BINSC:
5273 switch (code) {
5274 case V_POW:
5275 vp->Opcode = VP_OPCODE_POW;
5276 break;
5277 }
5278 if (parse_masked_dst_reg
5279 (ctx, inst, vc_head, Program, (GLint *) & vp->DstReg.File,
5280 &vp->DstReg.Index, vp->DstReg.WriteMask))
5281 return 1;
5282 for (a = 0; a < 2; a++) {
5283 if (parse_scalar_src_reg
5284 (ctx, inst, vc_head, Program, (GLint *) & vp->SrcReg[a].File,
5285 &vp->SrcReg[a].Index, &vp->SrcReg[a].Negate,
5286 vp->SrcReg[a].Swizzle))
5287 return 1;
5288 }
5289 break;
5290
5291 case V_GEN_BIN:
5292 switch (code) {
5293 case V_ADD:
5294 vp->Opcode = VP_OPCODE_ADD;
5295 break;
5296 case V_DP3:
5297 vp->Opcode = VP_OPCODE_DP3;
5298 break;
5299 case V_DP4:
5300 vp->Opcode = VP_OPCODE_DP4;
5301 break;
5302 case V_DPH:
5303 vp->Opcode = VP_OPCODE_DPH;
5304 break;
5305 case V_DST:
5306 vp->Opcode = VP_OPCODE_DST;
5307 break;
5308 case V_MAX:
5309 vp->Opcode = VP_OPCODE_MAX;
5310 break;
5311 case V_MIN:
5312 vp->Opcode = VP_OPCODE_MIN;
5313 break;
5314 case V_MUL:
5315 vp->Opcode = VP_OPCODE_MUL;
5316 break;
5317 case V_SGE:
5318 vp->Opcode = VP_OPCODE_SGE;
5319 break;
5320 case V_SLT:
5321 vp->Opcode = VP_OPCODE_SLT;
5322 break;
5323 case V_SUB:
5324 vp->Opcode = VP_OPCODE_SUB;
5325 break;
5326 case V_XPD:
5327 vp->Opcode = VP_OPCODE_XPD;
5328 break;
5329 }
5330 if (parse_masked_dst_reg
5331 (ctx, inst, vc_head, Program, (GLint *) & vp->DstReg.File,
5332 &vp->DstReg.Index, vp->DstReg.WriteMask))
5333 return 1;
5334 for (a = 0; a < 2; a++) {
5335 if (parse_vector_src_reg
5336 (ctx, inst, vc_head, Program, (GLint *) & vp->SrcReg[a].File,
5337 &vp->SrcReg[a].Index, &vp->SrcReg[a].Negate,
5338 vp->SrcReg[a].Swizzle))
5339 return 1;
5340 }
5341 break;
5342
5343 case V_GEN_TRI:
5344 switch (code) {
5345 case V_MAD:
5346 vp->Opcode = VP_OPCODE_MAD;
5347 break;
5348 }
5349
5350 if (parse_masked_dst_reg
5351 (ctx, inst, vc_head, Program, (GLint *) & vp->DstReg.File,
5352 &vp->DstReg.Index, vp->DstReg.WriteMask))
5353 return 1;
5354 for (a = 0; a < 3; a++) {
5355 if (parse_vector_src_reg
5356 (ctx, inst, vc_head, Program, (GLint *) & vp->SrcReg[a].File,
5357 &vp->SrcReg[a].Index, &vp->SrcReg[a].Negate,
5358 vp->SrcReg[a].Swizzle))
5359 return 1;
5360 }
5361 break;
5362
5363 case V_GEN_SWZ:
5364 switch (code) {
5365 case V_SWZ:
5366 vp->Opcode = VP_OPCODE_SWZ;
5367 break;
5368 }
5369 if (parse_masked_dst_reg
5370 (ctx, inst, vc_head, Program, (GLint *) & vp->DstReg.File,
5371 &vp->DstReg.Index, vp->DstReg.WriteMask))
5372 return 1;
5373
5374 if (parse_src_reg
5375 (ctx, inst, vc_head, Program, (GLint *) & vp->SrcReg[0].File,
5376 &vp->SrcReg[0].Index))
5377 return 1;
5378 parse_extended_swizzle_mask (inst, vp->SrcReg[0].Swizzle,
5379 &vp->SrcReg[0].Negate);
5380 break;
5381 }
5382 return 0;
5383 }
5384
5385 #if DEBUG_PARSING
5386
5387 static GLvoid
5388 print_state_token (GLint token)
5389 {
5390 switch (token) {
5391 case STATE_MATERIAL:
5392 fprintf (stderr, "STATE_MATERIAL ");
5393 break;
5394 case STATE_LIGHT:
5395 fprintf (stderr, "STATE_LIGHT ");
5396 break;
5397
5398 case STATE_LIGHTMODEL_AMBIENT:
5399 fprintf (stderr, "STATE_AMBIENT ");
5400 break;
5401
5402 case STATE_LIGHTMODEL_SCENECOLOR:
5403 fprintf (stderr, "STATE_SCENECOLOR ");
5404 break;
5405
5406 case STATE_LIGHTPROD:
5407 fprintf (stderr, "STATE_LIGHTPROD ");
5408 break;
5409
5410 case STATE_TEXGEN:
5411 fprintf (stderr, "STATE_TEXGEN ");
5412 break;
5413
5414 case STATE_FOG_COLOR:
5415 fprintf (stderr, "STATE_FOG_COLOR ");
5416 break;
5417
5418 case STATE_FOG_PARAMS:
5419 fprintf (stderr, "STATE_FOG_PARAMS ");
5420 break;
5421
5422 case STATE_CLIPPLANE:
5423 fprintf (stderr, "STATE_CLIPPLANE ");
5424 break;
5425
5426 case STATE_POINT_SIZE:
5427 fprintf (stderr, "STATE_POINT_SIZE ");
5428 break;
5429
5430 case STATE_POINT_ATTENUATION:
5431 fprintf (stderr, "STATE_ATTENUATION ");
5432 break;
5433
5434 case STATE_MATRIX:
5435 fprintf (stderr, "STATE_MATRIX ");
5436 break;
5437
5438 case STATE_MODELVIEW:
5439 fprintf (stderr, "STATE_MODELVIEW ");
5440 break;
5441
5442 case STATE_PROJECTION:
5443 fprintf (stderr, "STATE_PROJECTION ");
5444 break;
5445
5446 case STATE_MVP:
5447 fprintf (stderr, "STATE_MVP ");
5448 break;
5449
5450 case STATE_TEXTURE:
5451 fprintf (stderr, "STATE_TEXTURE ");
5452 break;
5453
5454 case STATE_PROGRAM:
5455 fprintf (stderr, "STATE_PROGRAM ");
5456 break;
5457
5458 case STATE_MATRIX_INVERSE:
5459 fprintf (stderr, "STATE_INVERSE ");
5460 break;
5461
5462 case STATE_MATRIX_TRANSPOSE:
5463 fprintf (stderr, "STATE_TRANSPOSE ");
5464 break;
5465
5466 case STATE_MATRIX_INVTRANS:
5467 fprintf (stderr, "STATE_INVTRANS ");
5468 break;
5469
5470 case STATE_AMBIENT:
5471 fprintf (stderr, "STATE_AMBIENT ");
5472 break;
5473
5474 case STATE_DIFFUSE:
5475 fprintf (stderr, "STATE_DIFFUSE ");
5476 break;
5477
5478 case STATE_SPECULAR:
5479 fprintf (stderr, "STATE_SPECULAR ");
5480 break;
5481
5482 case STATE_EMISSION:
5483 fprintf (stderr, "STATE_EMISSION ");
5484 break;
5485
5486 case STATE_SHININESS:
5487 fprintf (stderr, "STATE_SHININESS ");
5488 break;
5489
5490 case STATE_HALF:
5491 fprintf (stderr, "STATE_HALF ");
5492 break;
5493
5494 case STATE_POSITION:
5495 fprintf (stderr, "STATE_POSITION ");
5496 break;
5497
5498 case STATE_ATTENUATION:
5499 fprintf (stderr, "STATE_ATTENUATION ");
5500 break;
5501
5502 case STATE_SPOT_DIRECTION:
5503 fprintf (stderr, "STATE_DIRECTION ");
5504 break;
5505
5506 case STATE_TEXGEN_EYE_S:
5507 fprintf (stderr, "STATE_TEXGEN_EYE_S ");
5508 break;
5509
5510 case STATE_TEXGEN_EYE_T:
5511 fprintf (stderr, "STATE_TEXGEN_EYE_T ");
5512 break;
5513
5514 case STATE_TEXGEN_EYE_R:
5515 fprintf (stderr, "STATE_TEXGEN_EYE_R ");
5516 break;
5517
5518 case STATE_TEXGEN_EYE_Q:
5519 fprintf (stderr, "STATE_TEXGEN_EYE_Q ");
5520 break;
5521
5522 case STATE_TEXGEN_OBJECT_S:
5523 fprintf (stderr, "STATE_TEXGEN_EYE_S ");
5524 break;
5525
5526 case STATE_TEXGEN_OBJECT_T:
5527 fprintf (stderr, "STATE_TEXGEN_OBJECT_T ");
5528 break;
5529
5530 case STATE_TEXGEN_OBJECT_R:
5531 fprintf (stderr, "STATE_TEXGEN_OBJECT_R ");
5532 break;
5533
5534 case STATE_TEXGEN_OBJECT_Q:
5535 fprintf (stderr, "STATE_TEXGEN_OBJECT_Q ");
5536 break;
5537
5538 case STATE_TEXENV_COLOR:
5539 fprintf (stderr, "STATE_TEXENV_COLOR ");
5540 break;
5541
5542 case STATE_DEPTH_RANGE:
5543 fprintf (stderr, "STATE_DEPTH_RANGE ");
5544 break;
5545
5546 case STATE_VERTEX_PROGRAM:
5547 fprintf (stderr, "STATE_VERTEX_PROGRAM ");
5548 break;
5549
5550 case STATE_FRAGMENT_PROGRAM:
5551 fprintf (stderr, "STATE_FRAGMENT_PROGRAM ");
5552 break;
5553
5554 case STATE_ENV:
5555 fprintf (stderr, "STATE_ENV ");
5556 break;
5557
5558 case STATE_LOCAL:
5559 fprintf (stderr, "STATE_LOCAL ");
5560 break;
5561
5562 }
5563 fprintf (stderr, "[%d] ", token);
5564 }
5565
5566
5567 static GLvoid
5568 debug_variables (GLcontext * ctx, struct var_cache *vc_head,
5569 struct arb_program *Program)
5570 {
5571 struct var_cache *vc;
5572 GLint a, b;
5573
5574 fprintf (stderr, "debug_variables, vc_head: %x\n", vc_head);
5575
5576 /* First of all, print out the contents of the var_cache */
5577 vc = vc_head;
5578 while (vc) {
5579 fprintf (stderr, "[%x]\n", vc);
5580 switch (vc->type) {
5581 case vt_none:
5582 fprintf (stderr, "UNDEFINED %s\n", vc->name);
5583 break;
5584 case vt_attrib:
5585 fprintf (stderr, "ATTRIB %s\n", vc->name);
5586 fprintf (stderr, " binding: 0x%x\n", vc->attrib_binding);
5587 break;
5588 case vt_param:
5589 fprintf (stderr, "PARAM %s begin: %d len: %d\n", vc->name,
5590 vc->param_binding_begin, vc->param_binding_length);
5591 b = vc->param_binding_begin;
5592 for (a = 0; a < vc->param_binding_length; a++) {
5593 fprintf (stderr, "%s\n",
5594 Program->Parameters->Parameters[a + b].Name);
5595 if (Program->Parameters->Parameters[a + b].Type == STATE) {
5596 print_state_token (Program->Parameters->Parameters[a + b].
5597 StateIndexes[0]);
5598 print_state_token (Program->Parameters->Parameters[a + b].
5599 StateIndexes[1]);
5600 print_state_token (Program->Parameters->Parameters[a + b].
5601 StateIndexes[2]);
5602 print_state_token (Program->Parameters->Parameters[a + b].
5603 StateIndexes[3]);
5604 print_state_token (Program->Parameters->Parameters[a + b].
5605 StateIndexes[4]);
5606 print_state_token (Program->Parameters->Parameters[a + b].
5607 StateIndexes[5]);
5608 }
5609 else
5610 fprintf (stderr, "%f %f %f %f\n",
5611 Program->Parameters->Parameters[a + b].Values[0],
5612 Program->Parameters->Parameters[a + b].Values[1],
5613 Program->Parameters->Parameters[a + b].Values[2],
5614 Program->Parameters->Parameters[a + b].Values[3]);
5615 }
5616 break;
5617 case vt_temp:
5618 fprintf (stderr, "TEMP %s\n", vc->name);
5619 fprintf (stderr, " binding: 0x%x\n", vc->temp_binding);
5620 break;
5621 case vt_output:
5622 fprintf (stderr, "OUTPUT %s\n", vc->name);
5623 fprintf (stderr, " binding: 0x%x\n", vc->output_binding);
5624 break;
5625 case vt_alias:
5626 fprintf (stderr, "ALIAS %s\n", vc->name);
5627 fprintf (stderr, " binding: 0x%x (%s)\n",
5628 vc->alias_binding, vc->alias_binding->name);
5629 break;
5630 }
5631 vc = vc->next;
5632 }
5633 }
5634
5635 #endif
5636
5637
5638 /**
5639 * The main loop for parsing a fragment or vertex program
5640 *
5641 * \return 0 on sucess, 1 on error
5642 */
5643 static GLint
5644 parse_arb_program (GLcontext * ctx, GLubyte * inst, struct var_cache **vc_head,
5645 struct arb_program *Program)
5646 {
5647 GLint err = 0;
5648
5649 Program->MajorVersion = (GLuint) * inst++;
5650 Program->MinorVersion = (GLuint) * inst++;
5651
5652 while (*inst != END) {
5653 switch (*inst++) {
5654
5655 case OPTION:
5656 switch (*inst++) {
5657 case ARB_PRECISION_HINT_FASTEST:
5658 Program->HintPrecisionFastest = 1;
5659 break;
5660
5661 case ARB_PRECISION_HINT_NICEST:
5662 Program->HintPrecisionNicest = 1;
5663 break;
5664
5665 case ARB_FOG_EXP:
5666 Program->HintFogExp = 1;
5667 break;
5668
5669 case ARB_FOG_EXP2:
5670 Program->HintFogExp2 = 1;
5671 break;
5672
5673 case ARB_FOG_LINEAR:
5674 Program->HintFogLinear = 1;
5675 break;
5676
5677 case ARB_POSITION_INVARIANT:
5678 Program->HintPositionInvariant = 1;
5679 break;
5680 }
5681 break;
5682
5683 case INSTRUCTION:
5684 Program->Position = parse_position (&inst);
5685
5686 if (Program->type == GL_FRAGMENT_PROGRAM_ARB) {
5687 /* Realloc Program->FPInstructions */
5688 Program->FPInstructions =
5689 (struct fp_instruction *) _mesa_realloc (Program->FPInstructions,
5690 Program->Base.NumInstructions*sizeof(struct fp_instruction),
5691 (Program->Base.NumInstructions+1)*sizeof (struct fp_instruction));
5692
5693 /* parse the current instruction */
5694 err = parse_fp_instruction (ctx, &inst, vc_head, Program,
5695 &Program->FPInstructions[Program->Base.NumInstructions]);
5696
5697 }
5698 else {
5699 /* Realloc Program->VPInstructions */
5700 Program->VPInstructions =
5701 (struct vp_instruction *) _mesa_realloc (Program->VPInstructions,
5702 Program->Base.NumInstructions*sizeof(struct vp_instruction),
5703 (Program->Base.NumInstructions +1)*sizeof(struct vp_instruction));
5704
5705 /* parse the current instruction */
5706 err = parse_vp_instruction (ctx, &inst, vc_head, Program,
5707 &Program->VPInstructions[Program->Base.NumInstructions]);
5708 }
5709
5710 /* increment Program->Base.NumInstructions */
5711 Program->Base.NumInstructions++;
5712 break;
5713
5714 case DECLARATION:
5715 err = parse_declaration (ctx, &inst, vc_head, Program);
5716 break;
5717
5718 default:
5719 break;
5720 }
5721
5722 if (err)
5723 break;
5724 }
5725
5726 /* Finally, tag on an OPCODE_END instruction */
5727 if (Program->type == GL_FRAGMENT_PROGRAM_ARB) {
5728 Program->FPInstructions =
5729 (struct fp_instruction *) _mesa_realloc (Program->FPInstructions,
5730 Program->Base.NumInstructions*sizeof(struct fp_instruction),
5731 (Program->Base.NumInstructions+1)*sizeof(struct fp_instruction));
5732
5733 Program->FPInstructions[Program->Base.NumInstructions].Opcode = FP_OPCODE_END;
5734 }
5735 else {
5736 Program->VPInstructions =
5737 (struct vp_instruction *) _mesa_realloc (Program->VPInstructions,
5738 Program->Base.NumInstructions*sizeof(struct vp_instruction),
5739 (Program->Base.NumInstructions+1)*sizeof(struct vp_instruction));
5740
5741 Program->VPInstructions[Program->Base.NumInstructions].Opcode = VP_OPCODE_END;
5742 }
5743
5744 /* increment Program->Base.NumInstructions */
5745 Program->Base.NumInstructions++;
5746
5747 return err;
5748 }
5749
5750
5751 /**
5752 * This kicks everything off.
5753 *
5754 * \param ctx - The GL Context
5755 * \param str - The program string
5756 * \param len - The program string length
5757 * \param Program - The arb_program struct to return all the parsed info in
5758 * \return 0 on sucess, 1 on error
5759 */
5760 GLuint
5761 _mesa_parse_arb_program (GLcontext * ctx, const GLubyte * str, GLsizei len,
5762 struct arb_program * program)
5763 {
5764 GLint a, err, error_pos;
5765 char error_msg[300];
5766 GLuint parsed_len;
5767 struct var_cache *vc_head;
5768 dict *dt;
5769 GLubyte *parsed, *inst;
5770
5771 #if DEBUG_PARSING
5772 fprintf (stderr, "Loading grammar text!\n");
5773 #endif
5774 dt = grammar_load_from_text ((GLubyte *) arb_grammar_text);
5775 if (!dt) {
5776 grammar_get_last_error ((GLubyte *) error_msg, 300, &error_pos);
5777 _mesa_set_program_error (ctx, error_pos, error_msg);
5778 _mesa_error (ctx, GL_INVALID_OPERATION,
5779 "Error loading grammer rule set");
5780 return 1;
5781 }
5782
5783 #if DEBUG_PARSING
5784 printf ("Checking Grammar!\n");
5785 #endif
5786 err = grammar_check (dt, str, &parsed, &parsed_len);
5787
5788
5789 /* Syntax parse error */
5790 if (err == 0) {
5791 grammar_get_last_error ((GLubyte *) error_msg, 300, &error_pos);
5792 _mesa_set_program_error (ctx, error_pos, error_msg);
5793 _mesa_error (ctx, GL_INVALID_OPERATION, "Parse Error");
5794
5795 dict_destroy (&dt);
5796 return 1;
5797 }
5798
5799 #if DEBUG_PARSING
5800 printf ("Destroying grammer dict [parse retval: %d]\n", err);
5801 #endif
5802 dict_destroy (&dt);
5803
5804 /* Initialize the arb_program struct */
5805 program->Base.NumInstructions =
5806 program->Base.NumTemporaries =
5807 program->Base.NumParameters =
5808 program->Base.NumAttributes = program->Base.NumAddressRegs = 0;
5809 program->Parameters = _mesa_new_parameter_list ();
5810 program->InputsRead = 0;
5811 program->OutputsWritten = 0;
5812 program->Position = 0;
5813 program->MajorVersion = program->MinorVersion = 0;
5814 program->HintPrecisionFastest =
5815 program->HintPrecisionNicest =
5816 program->HintFogExp2 =
5817 program->HintFogExp =
5818 program->HintFogLinear = program->HintPositionInvariant = 0;
5819 for (a = 0; a < MAX_TEXTURE_IMAGE_UNITS; a++)
5820 program->TexturesUsed[a] = 0;
5821 program->NumAluInstructions =
5822 program->NumTexInstructions =
5823 program->NumTexIndirections = 0;
5824
5825 program->FPInstructions = NULL;
5826 program->VPInstructions = NULL;
5827
5828 vc_head = NULL;
5829 err = 0;
5830
5831 /* Start examining the tokens in the array */
5832 inst = parsed;
5833
5834 /* Check the grammer rev */
5835 if (*inst++ != REVISION) {
5836 _mesa_set_program_error (ctx, 0, "Grammar version mismatch");
5837 _mesa_error (ctx, GL_INVALID_OPERATION, "Grammar verison mismatch");
5838 err = 1;
5839 }
5840 else {
5841 switch (*inst++) {
5842 case FRAGMENT_PROGRAM:
5843 program->type = GL_FRAGMENT_PROGRAM_ARB;
5844 break;
5845
5846 case VERTEX_PROGRAM:
5847 program->type = GL_VERTEX_PROGRAM_ARB;
5848 break;
5849 }
5850
5851 err = parse_arb_program (ctx, inst, &vc_head, program);
5852 #if DEBUG_PARSING
5853 fprintf (stderr, "Symantic analysis returns %d [1 is bad!]\n", err);
5854 #endif
5855 }
5856
5857 /*debug_variables(ctx, vc_head, program); */
5858
5859 /* We're done with the parsed binary array */
5860 var_cache_destroy (&vc_head);
5861
5862 _mesa_free (parsed);
5863 #if DEBUG_PARSING
5864 printf ("_mesa_parse_arb_program() done\n");
5865 #endif
5866 return err;
5867 }