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