1 %{
2 //////////////////////////////////////////////////////////////////////
3 //
4 //                             Pixie
5 //
6 // Copyright � 1999 - 2003, Okan Arikan
7 //
8 // Contact: okan@cs.utexas.edu
9 //
10 //	This library is free software; you can redistribute it and/or
11 //	modify it under the terms of the GNU Lesser General Public
12 //	License as published by the Free Software Foundation; either
13 //	version 2.1 of the License, or (at your option) any later version.
14 //
15 //	This library is distributed in the hope that it will be useful,
16 //	but WITHOUT ANY WARRANTY; without even the implied warranty of
17 //	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18 //	Lesser General Public License for more details.
19 //
20 //	You should have received a copy of the GNU Lesser General Public
21 //	License along with this library; if not, write to the Free Software
22 //	Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
23 //
24 ///////////////////////////////////////////////////////////////////////
25 ///////////////////////////////////////////////////////////////////////
26 //
27 //  File				:	rib.y
28 //  Classes				:	-
29 //  Description			:	RIB bindings
30 //
31 ////////////////////////////////////////////////////////////////////////
32 #undef alloca
33 #define	YYMAXDEPTH	100000
34 
35 
36 #include "common/global.h"
37 #include "common/containers.h"
38 #include "common/os.h"
39 #include "ri.h"
40 #include "delayed.h"
41 #include "rib.h"
42 #include "rendererContext.h"
43 #include "renderer.h"
44 #include "error.h"
45 #include "ri_config.h"
46 
47 #include <math.h>
48 #include <string.h>
49 #include <stdarg.h>
50 
51 
52 #ifdef HAVE_ZLIB
53 #include <zlib.h>
54 #endif
55 
56 %}
57 
58 %union ribval {
59 	float	real;
60 	char	*string;
61 	int		integer;
62 }
63 
64 %{
65 // Some forward definitions
66 		int						riblex(ribval*);				// Forward definition for stupid yacc
67 		void					riberror(const char *,...);
68 
69 // Types for the data encountered in the rib file
70 // Note that there's no type for integer as they are recovered from floats
71 typedef enum {
72 	RT_FLOAT,
73 	RT_TEXT,
74 	RT_STAR,
75 	RT_PL,
76 	RT_NULL
77 } ERIBType;
78 
79 // Holds information about a parameter
80 typedef struct {
81 	char			*name;			// Name of the parameter
82 	ERIBType		type;			// Type of the parameter
83 	int				numItems;		// Number of items of type ERIBValue
84 	int				valuesStart;	// Index in the argument list where the parameter starts
85 } TParameter;
86 
87 typedef struct TLight {
88 	char			*name;			// The name of the light (if any)
89 	RtLightHandle	handle;			// The returned handle
90 	TLight			*next;			// The next light in the list
91 	int				index;			// The index of the light
92 } TLight;
93 
94 typedef struct TObject {
95 	RtObjectHandle	handle;			// The handle of the object
96 	TObject			*next;			// The next in the list
97 	char			*name;			// The name of the object (NULL if not named)
98 	int				index;			// The index of the object (-1 if named)
99 } TObject;
100 
101 static	int					ribDepth						=	0;		// The rib parsing stack depth
102 static	int					numConstant						=	0;		// The number of constant
103 static	int					numVertex						=	0;		// The number of vertices
104 static	int					numVarying						=	0;		// The number of varyings
105 static	int					numFaceVarying					=	0;		// The number of facevaryings
106 static	int					numUniform						=	0;		// The number of uniforms
107 static	TLight				*lights							=	NULL;	// The linked list of light handles
108 static	TObject				*objects						=	NULL;	// The linked list of object handles
109 static	void				(*callback)(const char *,...)	=	NULL;	// The callback function for the parser
110 
111 static	TMemCheckpoint		worldCheckpoint;
112 static	TMemCheckpoint		memoryCheckpoint;						// We use this to put a checkpoint to the memory
113 static	CArray<float>		floatArgs;								// The array of float arguments
114 static	CArray<int>			intArgs;								// The array of integer arguments
115 static	CArray<const char*>	stringArgs;								// The array of string arguments
116 
117 static	int					numParameters				=	0;
118 static	int					maxParameter				=	0;
119 static	RtToken				*tokens						=	NULL;
120 static	RtPointer			*vals						=	NULL;
121 static	TParameter			*parameters					=	NULL;
122 
123 		const char			*ribFile					=	NULL;	// The RIB file that we're parsing now
124 		int					ribLineno					=	-1;		// The line number in the rib file (where the parser is at)
125 		int					ribCommandLineno			=	-1;		// The line number of the last executed command in the RIB
126 
127 
128 #define	paramCheck()														\
129 	if (numParameters == maxParameter) {									\
130 		RtToken		*tmpTokens		=	new RtToken[maxParameter+10];		\
131 		RtPointer	*tmpVals		=	new RtPointer[maxParameter+10];		\
132 		TParameter	*tmpParameters	=	new TParameter[maxParameter+10];	\
133 																			\
134 		memcpy(tmpTokens,		tokens,maxParameter*sizeof(RtToken));		\
135 		memcpy(tmpVals,			vals,maxParameter*sizeof(RtPointer));		\
136 		memcpy(tmpParameters,	parameters,maxParameter*sizeof(TParameter));\
137 																			\
138 		delete [] tokens;													\
139 		delete [] vals;														\
140 		delete [] parameters;												\
141 																			\
142 		tokens						=	tmpTokens;							\
143 		vals						=	tmpVals;							\
144 		parameters					=	tmpParameters;						\
145 																			\
146 		maxParameter				+=	10;									\
147 	}
148 
149 #define	getFloat(__n)		(floatArgs.array + __n)
150 #define	getInt(__n)			(intArgs.array + __n)
151 #define	getString(__n)		(stringArgs.array + __n)
152 
153 // Some textual descriptions for the rib-ri parser
154 
155 // Basis functions
156 const	char	*RI_BEZIERBASIS				=	"bezier";
157 const	char	*RI_BSPLINEBASIS			=	"b-spline";
158 const	char	*RI_POWERBASIS				=	"power";
159 const	char	*RI_CATMULLROMBASIS			=	"catmull-rom";
160 const	char	*RI_HERMITEBASIS			=	"hermite";
161 
162 // Error handlers
163 const	char	*RI_ERRORIGNORE				=	"ignore";
164 const	char	*RI_ERRORPRINT				=	"print";
165 const	char	*RI_ERRORABORT				=	"abort";
166 
167 // Predefined procedural handlers
168 const	char	*RI_PROCDELAYEDREADARCHIVE	=	"DelayedReadArchive";
169 const	char	*RI_PROCRUNPROGRAM			=	"RunProgram";
170 const	char	*RI_PROCDYNAMICLOAD			=	"DynamicLoad";
171 
172 // Predefined error handlers
173 const	char	*RI_ERROR_IGNORE			=	"ignore";
174 const	char	*RI_ERROR_ABORT				=	"abort";
175 const	char	*RI_ERROR_PRINT				=	"print";
176 
177 void	test();
178 
179 ///////////////////////////////////////////////////////////////////////
180 // Function				:	toLowerCase
181 // Description			:	Convert the argument to lowercase
182 // Return Value			:	Pointer to the argument
183 // Comments				:
toLowerCase(char * s)184 static	char			*toLowerCase(char *s) {
185 	int	i;
186 	int	l	=	(int) strlen(s);
187 
188 	for (i=0;i<l;i++) {
189 		if ((s[i] >= 'A') && (s[i] <= 'Z'))
190 			s[i]	=	'a'+s[i]-'A';
191 	}
192 
193 	return s;
194 }
195 
196 
197 ///////////////////////////////////////////////////////////////////////
198 // Function				:	parameterListCheck
199 // Description			:	Count the number of variables in the parameter list
200 // Return Value			:	TRUE if OK
201 // Comments				:	(This version is used by the primitives)
parameterListCheck()202 static	int		parameterListCheck() {
203 	int			i;
204 	CVariable	tmp;
205 
206 	// Set the number of variables
207 	numConstant		=	0;
208 	numVertex		=	0;
209 	numVarying		=	0;
210 	numFaceVarying	=	0;
211 	numUniform		=	0;
212 
213 	// For each parameter encountered
214 	for (i=0;i<numParameters;i++) {
215 		TParameter		*par	=	parameters+i;
216 		CVariable		*var	=	CRenderer::retrieveVariable(par->name);
217 		EVariableClass	container;
218 
219 		// Get the variable container to check the number of items
220 		if (var == NULL) {
221 			if (parseVariable(&tmp,NULL,par->name)) {
222 				// We have an inline declaration, use that container
223 				container	=	tmp.container;
224 				var			=	&tmp;
225 			} else {
226 				if (FALSE) { 	// If we want to go through the shader parameters (performance hit)
227 					// Not global, not inline, check the shaders
228 					CAttributes	*attributes	=	CRenderer::context->getAttributes(FALSE);
229 					var						=	attributes->findParameter(par->name);
230 
231 					if (var != NULL) {
232 						container	=	var->container;
233 					} else {
234 						// This isn't a globally declared variable
235 						// Neither is it an inline delcaration
236 						error(CODE_BADTOKEN,"Parameter \"%s\" is not declared\n",par->name);
237 						return FALSE;
238 					}
239 				} else {
240 					// This isn't a globally declared variable
241 					// Neither is it an inline delcaration
242 					error(CODE_BADTOKEN,"Parameter \"%s\" is not declared\n",par->name);
243 					return FALSE;
244 				}
245 			}
246 		} else {
247 			// This variable is predeclared.  It may or may not be a global though
248 			container	=	var->container;
249 		}
250 
251 		// Handle some irregular cases
252 		if (var == NULL) {
253 			// Special symbols
254 			if (strcmp(par->name,"Pz") == 0) {
255 				tmp.numFloats	=	1;
256 				tmp.numItems	=	1;
257 				tmp.entry		=	VARIABLE_P;
258 				strcpy(tmp.name,"Pz");
259 				tmp.type		=	TYPE_FLOAT;
260 				tmp.container	=	CONTAINER_VERTEX;
261 				tmp.usageMarker	=	PARAMETER_P;
262 				var				=	&tmp;
263 				container		=	var->container;
264 			} else if (strcmp(par->name,"Np") == 0) {
265 				tmp.numFloats	=	3;
266 				tmp.numItems	=	1;
267 				tmp.entry		=	VARIABLE_NG;
268 				strcpy(tmp.name,"Np");
269 				tmp.type		=	TYPE_NORMAL;
270 				tmp.container	=	CONTAINER_VERTEX;
271 				tmp.usageMarker	=	PARAMETER_NG;
272 				var				=	&tmp;
273 				container		=	var->container;
274 			} else if (strcmp(par->name,"Pw") == 0) {
275 				tmp.numFloats	=	4;
276 				tmp.numItems	=	1;
277 				tmp.entry		=	VARIABLE_P;
278 				strcpy(tmp.name,"Pw");
279 				tmp.type		=	TYPE_POINT;
280 				tmp.container	=	CONTAINER_VERTEX;
281 				tmp.usageMarker	=	PARAMETER_P;
282 				var				=	&tmp;
283 				container		=	var->container;
284 			}
285 		}
286 
287 		if (var == NULL)	{
288 			error(CODE_BADTOKEN,"Parameter \"%s\" is not declared\n",par->name);
289 			return FALSE;
290 		}
291 
292 		if ((par->numItems % var->numFloats) != 0) {
293 			error(CODE_MISSINGDATA,"Invalid number of items for the parameter \"%s\" (expecting n*%d, found %d)\n",par->name,var->numFloats,par->numItems);
294 			return FALSE;
295 		}
296 
297 		// Type checking
298 		if (var->type == TYPE_INTEGER) {
299 			if (par->type == RT_FLOAT) {
300 				// We need to convert the float argument list to int
301 				int	j;
302 				T32	*dest	=	(T32 *) vals[i];
303 
304 				// FIXME: We're doing an ugly conversion here
305 				// These assertions must be valid even on 64 bit platforms
306 				assert(sizeof(T32) == 4);
307 				assert(sizeof(float) == sizeof(int));
308 
309 				for (j=par->numItems;j>0;j--,dest++) {
310 					dest->integer	=	(int) dest->real;
311 				}
312 			} else {
313 				error(CODE_RANGE,"Type mismatch for parameter \"%s\" (expecting integer, found string)\n",par->name);
314 				return	FALSE;
315 			}
316 		} else if (var->type == TYPE_STRING) {
317 			if (par->type != RT_TEXT) {
318 				error(CODE_RANGE,"Type mismatch for parameter \"%s\" (expecting string, found float)\n",par->name);
319 				return	FALSE;
320 			}
321 		} else {
322 			if (par->type != RT_FLOAT) {
323 				error(CODE_RANGE,"Type mismatch for parameter \"%s\" (expecting float, found string)\n",par->name);
324 				return	FALSE;
325 			}
326 		}
327 
328 #define	SIZECHECK(dest)																		\
329 			if (dest == 0) {																\
330 				dest = (par->numItems / var->numFloats);									\
331 			} else {																		\
332 				if (dest != (par->numItems / var->numFloats)) {								\
333 					error(CODE_RANGE,"Invalid number of items for the parameter \"%s\" (expecting %d, found %d)\n",par->name,dest,par->numItems/var->numFloats);	\
334 					return FALSE;															\
335 				}																			\
336 			}
337 
338 		switch(container) {
339 		case CONTAINER_UNIFORM:
340 			SIZECHECK(numUniform);
341 			break;
342 		case CONTAINER_VERTEX:
343 			SIZECHECK(numVertex);
344 			break;
345 		case CONTAINER_VARYING:
346 			SIZECHECK(numVarying);
347 			break;
348 		case CONTAINER_FACEVARYING:
349 			SIZECHECK(numFaceVarying);
350 			break;
351 		case CONTAINER_CONSTANT:
352 			SIZECHECK(numConstant);
353 			break;
354 		default:
355 			error(CODE_BUG,"Unknown container class in parameter list\n");
356 			return FALSE;
357 			break;
358 		}
359 
360 #undef SIZECHECK
361 
362 	}
363 
364 	return TRUE;
365 }
366 
367 ///////////////////////////////////////////////////////////////////////
368 // Function				:	getBasis
369 // Description			:	Get the basis matrix from a given text
370 // Return Value			:	TRUE if OK
371 // Comments				:
sizeCheck(int numExpVertex,int numExpVarying,int numExpFaceVarying,int numExpUniform)372 static	int		sizeCheck(int numExpVertex,int numExpVarying,int numExpFaceVarying,int numExpUniform) {
373 	if (numExpVarying == 0)		numExpVarying		=	numExpVertex;
374 	if (numExpVertex == 0)		numExpVertex		=	numExpVarying;
375 	if (numExpFaceVarying == 0)	numExpFaceVarying	=	numExpVertex;
376 
377 	if (numConstant != 0) {
378 		if (numConstant != 1) {
379 			error(CODE_CONSISTENCY,"Unexpected number of constants (1 expected, %d found)\n",numVarying);
380 			return FALSE;
381 		}
382 	}
383 
384 	if (numVertex != 0) {
385 		if (numExpVertex != numVertex) {
386 			error(CODE_CONSISTENCY,"Unexpected number of vertices (%d expected, %d found)\n",numExpVertex,numVertex);
387 			return FALSE;
388 		}
389 	}
390 
391 	if (numVarying != 0) {
392 		if (numExpVarying != numVarying) {
393 			error(CODE_CONSISTENCY,"Unexpected number of varyings (%d expected, %d found)\n",numExpVarying,numVarying);
394 			return FALSE;
395 		}
396 	}
397 
398 	if (numFaceVarying != 0) {
399 		if (numExpFaceVarying != numFaceVarying) {
400 			error(CODE_CONSISTENCY,"Unexpected number of facevaryings (%d expected, %d found)\n",numExpFaceVarying,numFaceVarying);
401 			return FALSE;
402 		}
403 	}
404 
405 	if (numUniform != 0) {
406 		if (numExpUniform != numUniform) {
407 			error(CODE_CONSISTENCY,"Unexpected number of uniforms (%d expected, %d found)\n",numExpUniform,numUniform);
408 			return FALSE;
409 		}
410 	}
411 
412 	return TRUE;
413 }
414 
415 ///////////////////////////////////////////////////////////////////////
416 // Function				:	getBasis
417 // Description			:	Get the basis matrix from a given text
418 // Return Value			:	TRUE if OK
419 // Comments				:
getBasis(RtBasis ** a,char * n)420 static	int		getBasis(RtBasis **a,char *n) {
421 	char	*name	=	toLowerCase(n);
422 
423 	if (strcmp(name,RI_BEZIERBASIS) == 0)
424 		a[0]	=	&RiBezierBasis;
425 	else if (strcmp(name,RI_BSPLINEBASIS) == 0)
426 		a[0]	=	&RiBSplineBasis;
427 	else if (strcmp(name,RI_CATMULLROMBASIS) == 0)
428 		a[0]	=	&RiCatmullRomBasis;
429 	else if (strcmp(name,RI_HERMITEBASIS) == 0)
430 		a[0]	=	&RiHermiteBasis;
431 	else if (strcmp(name,RI_POWERBASIS) == 0)
432 		a[0]	=	&RiPowerBasis;
433 	else {
434 		error(CODE_BADTOKEN,"Unknown basis: \"%s\"\n",name);
435 		return	FALSE;
436 	}
437 
438 	return	TRUE;
439 }
440 
441 ///////////////////////////////////////////////////////////////////////
442 // Function				:	getFilter
443 // Description			:	Get the filter from a given text
444 // Return Value			:	NULL if failed
445 // Comments				:
getFilter(char * n)446 static	RtFilterFunc	getFilter(char *n) {
447 	char			*name	=	toLowerCase(n);
448 	RtFilterFunc	f		=	NULL;
449 
450 	if (strcmp(name,RI_BOXFILTER) == 0) {
451 		f = RiBoxFilter;
452 	} else if (strcmp(name,RI_GAUSSIANFILTER) == 0) {
453 		f = RiGaussianFilter;
454 	} else if (strcmp(name,RI_TRIANGLEFILTER) == 0) {
455 		f = RiTriangleFilter;
456 	} else if (strcmp(name,RI_CATMULLROMFILTER) == 0) {
457 		f = RiCatmullRomFilter;
458 	} else if (strcmp(name,RI_BLACKMANHARRISFILTER) == 0) {
459 		f = RiBlackmanHarrisFilter;
460 	} else if (strcmp(name,RI_MITCHELLFILTER) == 0) {
461 		f = RiMitchellFilter;
462 	} else if (strcmp(name,RI_SINCFILTER) == 0) {
463 		f = RiSincFilter;
464 	} else if (strcmp(name,RI_BESSELFILTER) == 0) {
465 		f = RiBesselFilter;
466 	} else if (strcmp(name,RI_DISKFILTER) == 0) {
467 		f = RiDiskFilter;
468 	} else {
469 		error(CODE_BADTOKEN,"Filter \"%s\" is not recognized\n",name);
470 	}
471 
472 	return f;
473 }
474 
475 ///////////////////////////////////////////////////////////////////////
476 // Function				:	getError
477 // Description			:	Get the error handler from a given text
478 // Return Value			:	NULL if failed
479 // Comments				:
getErrorHandler(char * n)480 static	RtErrorHandler	getErrorHandler(char *n) {
481 	char			*name	=	toLowerCase(n);
482 	RtErrorHandler	f		=	NULL;
483 
484 	if (strcmp(name,RI_ERRORIGNORE) == 0) {
485 		f = RiErrorPrint;
486 	} else if (strcmp(name,RI_ERRORPRINT) == 0) {
487 		f = RiErrorPrint;
488 	} else if (strcmp(name,RI_ERRORABORT) == 0) {
489 		f = RiErrorAbort;
490 	} else {
491 		error(CODE_BADTOKEN,"Error handler \"%s\" is not recognized\n",name);
492 	}
493 
494 	return f;
495 }
496 
497 
498 %}
499 %pure-parser
500 %token	RIB_DECLARE
501 %token	RIB_FRAME_BEGIN
502 %token	RIB_FRAME_END
503 %token	RIB_WORLD_BEGIN
504 %token	RIB_WORLD_END
505 %token	RIB_FORMAT
506 %token	RIB_FRAME_ASPECT_RATIO
507 %token	RIB_SCREEN_WINDOW
508 %token	RIB_CROP_WINDOW
509 %token	RIB_PROJECTION
510 %token	RIB_CLIPPING
511 %token	RIB_CLIPPING_PLANE
512 %token	RIB_DEPTH_OF_FIELD
513 %token	RIB_SHUTTER
514 %token	RIB_PIXEL_VARIANCE
515 %token	RIB_PIXEL_SAMPLES
516 %token	RIB_PIXEL_FILTER
517 %token	RIB_EXPOSURE
518 %token	RIB_IMAGER
519 %token	RIB_QUANTIZE
520 %token	RIB_DISPLAY
521 %token	RIB_DISPLAYCHANNEL
522 %token	RIB_HIDER
523 %token	RIB_COLOR_SAMPLES
524 %token	RIB_RELATIVE_DETAIL
525 %token	RIB_OPTION
526 %token	RIB_ATTRIBUTE_BEGIN
527 %token	RIB_ATTRIBUTE_END
528 %token	RIB_COLOR
529 %token	RIB_OPACITY
530 %token	RIB_TEXTURE_COORDINATES
531 %token	RIB_LIGHT_SOURCE
532 %token	RIB_AREA_LIGHT_SOURCE
533 %token	RIB_ILLUMINATE
534 %token	RIB_SURFACE
535 %token	RIB_ATMOSPHERE
536 %token	RIB_INTERIOR
537 %token	RIB_EXTERIOR
538 %token	RIB_SHADING_RATE
539 %token	RIB_SHADING_INTERPOLATION
540 %token	RIB_MATTE
541 %token	RIB_BOUND
542 %token	RIB_DETAIL
543 %token	RIB_DETAIL_RANGE
544 %token	RIB_GEOMETRIC_APPROXIMATION
545 %token	RIB_GEOMETRIC_REPRESENTATION
546 %token	RIB_ORIENTATION
547 %token	RIB_REVERSE_ORIENTATION
548 %token	RIB_SIDES
549 %token	RIB_IDENTITY
550 %token	RIB_TRANSFORM
551 %token	RIB_CONCAT_TRANSFORM
552 %token	RIB_PERSPECTIVE
553 %token	RIB_TRANSLATE
554 %token	RIB_ROTATE
555 %token	RIB_SCALE
556 %token	RIB_SKEW
557 %token	RIB_DEFORMATION
558 %token	RIB_DISPLACEMENT
559 %token	RIB_COORDINATE_SYSTEM
560 %token	RIB_COORDINATE_SYS_TRANSFORM
561 %token	RIB_TRANSFORM_BEGIN
562 %token	RIB_TRANSFORM_END
563 %token	RIB_ATTRIBUTE
564 %token	RIB_POLYGON
565 %token	RIB_GENERAL_POLYGON
566 %token	RIB_POINTS_POLYGONS
567 %token	RIB_POINTS_GENERAL_POLYGONS
568 %token	RIB_BASIS
569 %token	RIB_PATCH
570 %token	RIB_PATCH_MESH
571 %token	RIB_NU_PATCH
572 %token	RIB_TRIM_CURVE
573 %token	RIB_SPHERE
574 %token	RIB_CONE
575 %token	RIB_CYLINDER
576 %token	RIB_HYPERBOLOID
577 %token	RIB_PARABOLOID
578 %token	RIB_DISK
579 %token	RIB_TORUS
580 %token	RIB_CURVES
581 %token	RIB_GEOMETRY
582 %token	RIB_POINTS
583 %token	RIB_SUBDIVISION_MESH
584 %token	RIB_BLOBBY
585 %token	RIB_PROCEDURAL
586 %token	RIB_SOLID_BEGIN
587 %token	RIB_SOLID_END
588 %token	RIB_OBJECT_BEGIN
589 %token	RIB_OBJECT_END
590 %token	RIB_OBJECT_INSTANCE
591 %token	RIB_MOTION_BEGIN
592 %token	RIB_MOTION_END
593 %token	RIB_MAKE_TEXTURE
594 %token	RIB_MAKE_BRICKMAP
595 %token	RIB_MAKE_BUMP
596 %token	RIB_MAKE_LAT_LONG_ENVIRONMENT
597 %token	RIB_MAKE_CUBE_FACE_ENVIRONMENT
598 %token	RIB_MAKE_SHADOW
599 %token	RIB_ARCHIVE_RECORD
600 %token	RIB_ARCHIVE_BEGIN
601 %token	RIB_ARCHIVE_END
602 %token	RIB_RESOURCE
603 %token	RIB_RESOURCE_BEGIN
604 %token	RIB_RESOURCE_END
605 %token	RIB_IFBEGIN
606 %token	RIB_IFEND
607 %token	RIB_ELSEIF
608 %token	RIB_ELSE
609 %token	RIB_ERROR_HANDLER
610 %token	RIB_VERSION
611 %token	RIB_VERSION_STRING
612 %token	RIB_ARRAY_BEGIN
613 %token	RIB_ARRAY_END
614 %left<string>	RIB_TEXT
615 %token<real>	RIB_FLOAT
616 %token<string>	RIB_STRUCTURE_COMMENT
617 %type<integer>	ribFloats
618 %type<integer>	ribFloatString
619 %type<integer>	ribFloatArray
620 %type<integer>	ribIntString
621 %type<integer>	ribIntArray
622 %type<integer>	ribTextString
623 %type<integer>	ribTextArray
624 %start			start
625 %%
626 start:			ribCommands;
627 
628 
629 ribIntString:	ribIntString
630 				RIB_FLOAT
631 				{
632 					intArgs.push((int) $2);
633 					$$	=	$1	+	1;
634 				}
635 				|
636 				RIB_FLOAT
637 				{
638 					intArgs.push((int) $1);
639 					$$	=	1;
640 				}
641 				;
642 
643 
644 ribFloatString:	ribFloatString
645 				RIB_FLOAT
646 				{
647 					floatArgs.push($2);
648 					$$	=	$1	+	1;
649 				}
650 				|
651 				RIB_FLOAT
652 				{
653 					floatArgs.push($1);
654 					$$	=	1;
655 				}
656 				;
657 
658 ribTextString:	ribTextString
659 				RIB_TEXT
660 				{
661 					stringArgs.push($2);
662 					$$	=	$1	+	1;
663 				}
664 				|
665 				RIB_TEXT
666 				{
667 					stringArgs.push($1);
668 					$$	=	1;
669 				}
670 				;
671 
672 ribFloatArray:	RIB_ARRAY_BEGIN
673 				ribFloatString
674 				RIB_ARRAY_END
675 				{
676 					$$ = $2;
677 				}
678 				|
679 				RIB_ARRAY_BEGIN
680 				RIB_ARRAY_END
681 				{
682 					$$ = 0;
683 				}
684 				;
685 
686 
687 ribFloats:		ribFloatArray
688 				{
689 					$$	=	$1;
690 				}
691 				|
692 				ribFloatString
693 				{
694 					$$	=	$1;
695 				}
696 				;
697 
698 ribIntArray:	RIB_ARRAY_BEGIN
699 				ribIntString
700 				RIB_ARRAY_END
701 				{
702 					$$ = $2;
703 				}
704 				|
705 				RIB_ARRAY_BEGIN
706 				RIB_ARRAY_END
707 				{
708 					$$ = 0;
709 				}
710 				;
711 
712 
713 ribTextArray:	RIB_ARRAY_BEGIN
714 				ribTextString
715 				RIB_ARRAY_END
716 				{
717 					$$	=	$2;
718 				}
719 				|
720 				RIB_TEXT
721 				{
722 					stringArgs.push($1);
723 					$$	= 1;
724 				}
725 				;
726 
727 
728 
729 ribPL:			ribParameter
730 				ribPL
731 				{
732 				}
733 				|
734 				{
735 					int	i;
736 
737 					assert(numParameters < maxParameter);
738 
739 					// Fix the pointers
740 					for (i=0;i<numParameters;i++) {
741 						tokens[i]				=	parameters[i].name;
742 
743 						if (parameters[i].type == RT_TEXT)
744 							vals[i]				=	(RtPointer) (stringArgs.array + parameters[i].valuesStart);
745 						else
746 							vals[i]				=	(RtPointer) (floatArgs.array + parameters[i].valuesStart);
747 
748 					}
749 				}
750 				;
751 
752 ribParameter:	RIB_TEXT
753 				ribFloats
754 				{
755 					// A parameter is either a float array
756 					parameters[numParameters].name			=	$1;
757 					parameters[numParameters].type			=	RT_FLOAT;
758 					parameters[numParameters].numItems		=	$2;
759 					parameters[numParameters].valuesStart	=	floatArgs.numItems-$2;
760 					numParameters++;
761 					paramCheck();
762 				}
763 				|
764 				RIB_TEXT
765 				ribTextArray
766 				{
767 					// Or a string array
768 					parameters[numParameters].name			=	$1;
769 					parameters[numParameters].type			=	RT_TEXT;
770 					parameters[numParameters].numItems		=	$2;
771 					parameters[numParameters].valuesStart	=	stringArgs.numItems-$2;
772 					numParameters++;
773 					paramCheck();
774 				}
775 				;
776 
777 ribCommands:	ribCommands
778 				{
779 					// Save the line number in case we have an error
780 					ribCommandLineno		=	ribLineno;
781 
782 					// Reset the number of parameters
783 					floatArgs.numItems		=	0;
784 					intArgs.numItems		=	0;
785 					stringArgs.numItems		=	0;
786 					numParameters			=	0;
787 
788 					// Restore the memory
789 					memRestore(memoryCheckpoint,CRenderer::globalMemory);
790 				}
791 				ribComm
792 				{
793 				}
794 				|
795 				;
796 
797 
798 ribComm:		RIB_STRUCTURE_COMMENT
799 				{
800 					if (callback != NULL) {
801 						callback($1);
802 					}
803 				}
804 				|
805 				RIB_DECLARE
806 				RIB_TEXT
807 				RIB_TEXT
808 				{
809 					RiDeclare($2,$3);
810 				}
811 				|
812 				RIB_FRAME_BEGIN
813 				{
814 					RiFrameBegin(0);
815 				}
816 				|
817 				RIB_FRAME_BEGIN
818 				RIB_FLOAT
819 				{
820 					RiFrameBegin((int) $2);
821 				}
822 				|
823 				RIB_FRAME_END
824 				{
825 					RiFrameEnd();
826 				}
827 				|
828 				RIB_WORLD_BEGIN
829 				{
830 					// Save the checkpoint
831 					worldCheckpoint		=	memoryCheckpoint;
832 
833 					// Call the worldbegin
834 					RiWorldBegin();
835 
836 					// Create a new checkpoint because we allocate some stuff in RiWorldBegin
837 					memSave(memoryCheckpoint,CRenderer::globalMemory);
838 
839 				}
840 				|
841 				RIB_WORLD_END
842 				{
843 					RiWorldEnd();
844 
845 					// Restore the checkpoint to that before the world begin
846 					memoryCheckpoint	=	worldCheckpoint;
847 				}
848 				|
849 				RIB_FORMAT
850 				RIB_FLOAT
851 				RIB_FLOAT
852 				RIB_FLOAT
853 				{
854 					RiFormat((int) $2,(int) $3,$4);
855 				}
856 				|
857 				RIB_FRAME_ASPECT_RATIO
858 				RIB_FLOAT
859 				{
860 					RiFrameAspectRatio($2);
861 				}
862 				|
863 				RIB_SCREEN_WINDOW
864 				RIB_FLOAT
865 				RIB_FLOAT
866 				RIB_FLOAT
867 				RIB_FLOAT
868 				{
869 					RiScreenWindow($2,$3,$4,$5);
870 				}
871 				|
872 				RIB_SCREEN_WINDOW
873 				RIB_ARRAY_BEGIN
874 				RIB_FLOAT
875 				RIB_FLOAT
876 				RIB_FLOAT
877 				RIB_FLOAT
878 				RIB_ARRAY_END
879 				{
880 					RiScreenWindow($3,$4,$5,$6);
881 				}
882 				|
883 				RIB_CROP_WINDOW
884 				RIB_FLOAT
885 				RIB_FLOAT
886 				RIB_FLOAT
887 				RIB_FLOAT
888 				{
889 					RiCropWindow($2,$3,$4,$5);
890 				}
891 				|
892 				RIB_CROP_WINDOW
893 				RIB_ARRAY_BEGIN
894 				RIB_FLOAT
895 				RIB_FLOAT
896 				RIB_FLOAT
897 				RIB_FLOAT
898 				RIB_ARRAY_END
899 				{
900 					RiCropWindow($3,$4,$5,$6);
901 				}
902 				|
903 				RIB_PROJECTION
904 				RIB_TEXT
905 				ribPL
906 				{
907 					RiProjectionV($2,numParameters,tokens,vals);
908 				}
909 				|
910 				RIB_CLIPPING
911 				RIB_FLOAT
912 				RIB_FLOAT
913 				{
914 					RiClipping($2,$3);
915 				}
916 				|
917 				RIB_CLIPPING_PLANE
918 				RIB_FLOAT
919 				RIB_FLOAT
920 				RIB_FLOAT
921 				RIB_FLOAT
922 				RIB_FLOAT
923 				RIB_FLOAT
924 				{
925 					RiClippingPlane($2,$3,$4,$5,$6,$7);
926 				}
927 				|
928 				RIB_DEPTH_OF_FIELD
929 				RIB_FLOAT
930 				RIB_FLOAT
931 				RIB_FLOAT
932 				{
933 					RiDepthOfField($2,$3,$4);
934 				}
935 				|
936 				RIB_DEPTH_OF_FIELD
937 				{
938 					RiDepthOfField(C_INFINITY,1,1);
939 				}
940 				|
941 				RIB_SHUTTER
942 				RIB_FLOAT
943 				RIB_FLOAT
944 				{
945 					RiShutter($2,$3);
946 				}
947 				|
948 				RIB_PIXEL_VARIANCE
949 				RIB_FLOAT
950 				{
951 					RiPixelVariance($2);
952 				}
953 				|
954 				RIB_PIXEL_SAMPLES
955 				RIB_FLOAT
956 				RIB_FLOAT
957 				{
958 					RiPixelSamples($2,$3);
959 				}
960 				|
961 				RIB_PIXEL_FILTER
962 				RIB_TEXT
963 				RIB_FLOAT
964 				RIB_FLOAT
965 				{
966 					RtFilterFunc	f;
967 
968 					if ((f = getFilter($2)) != NULL) {
969 						RiPixelFilter(f,$3,$4);
970 					}
971 				}
972 				|
973 				RIB_EXPOSURE
974 				RIB_FLOAT
975 				RIB_FLOAT
976 				{
977 					RiExposure($2,$3);
978 				}
979 				|
980 				RIB_IMAGER
981 				RIB_TEXT
982 				ribPL
983 				{
984 					// No parameter list checking is performed for the shaders
985 					if (parameterListCheck()) {
986 						RiImagerV($2,numParameters,tokens,vals);
987 					}
988 				}
989 				|
990 				RIB_QUANTIZE
991 				RIB_TEXT
992 				RIB_FLOAT
993 				RIB_FLOAT
994 				RIB_FLOAT
995 				RIB_FLOAT
996 				{
997 					RiQuantize($2,(int) $3,(int) $4,(int) $5,$6);
998 				}
999 				|
1000 				RIB_DISPLAY
1001 				RIB_TEXT
1002 				RIB_TEXT
1003 				RIB_TEXT
1004 				ribPL
1005 				{
1006 					RiDisplayV($2,$3,$4,numParameters,tokens,vals);
1007 				}
1008 				|
1009 				RIB_DISPLAYCHANNEL
1010 				RIB_TEXT
1011 				ribPL
1012 				{
1013 					RiDisplayChannelV($2,numParameters,tokens,vals);
1014 				}
1015 				|
1016 				RIB_HIDER
1017 				RIB_TEXT
1018 				ribPL
1019 				{
1020 					if (parameterListCheck()) {
1021 						RiHiderV($2,numParameters,tokens,vals);
1022 					}
1023 				}
1024 				|
1025 				RIB_COLOR_SAMPLES
1026 				ribFloats
1027 				{
1028 					if ((floatArgs.numItems & 1) || ((floatArgs.numItems % 6) != 0)) {
1029 						error(CODE_MISSINGDATA,"ColorSamples: Invalid number of arguments (\"%d\")\n",floatArgs.numItems);
1030 					} else {
1031 						int		n		=	floatArgs.numItems/6;
1032 						float	*argf1	=	getFloat(0);
1033 						float	*argf2	=	getFloat(n*3);
1034 
1035 						RiColorSamples(n,argf1,argf2);
1036 					}
1037 				}
1038 				|
1039 				RIB_COLOR_SAMPLES
1040 				ribFloatArray
1041 				ribFloatArray
1042 				{
1043 					if (($2 != $3) || ((floatArgs.numItems % 6) != 0)) {
1044 						error(CODE_MISSINGDATA,"ColorSamples: Invalid number of arguments (\"%d\")\n",floatArgs.numItems);
1045 					} else {
1046 						int		n		=	floatArgs.numItems/6;
1047 						float	*argf1	=	getFloat(0);
1048 						float	*argf2	=	getFloat(n*3);
1049 
1050 						RiColorSamples(n,argf1,argf2);
1051 					}
1052 				}
1053 				|
1054 				RIB_RELATIVE_DETAIL
1055 				RIB_FLOAT
1056 				{
1057 					RiRelativeDetail($2);
1058 				}
1059 				|
1060 				RIB_OPTION
1061 				RIB_TEXT
1062 				ribPL
1063 				{
1064 					if (parameterListCheck()) {
1065 						RiOptionV($2,numParameters,tokens,vals);
1066 					}
1067 				}
1068 				|
1069 				RIB_ATTRIBUTE_BEGIN
1070 				{
1071 					RiAttributeBegin();
1072 				}
1073 				|
1074 				RIB_ATTRIBUTE_END
1075 				{
1076 					RiAttributeEnd();
1077 				}
1078 				|
1079 				RIB_COLOR
1080 				RIB_FLOAT
1081 				RIB_FLOAT
1082 				RIB_FLOAT
1083 				{
1084 					RtColor	color;
1085 
1086 					color[0]	=	$2;
1087 					color[1]	=	$3;
1088 					color[2]	=	$4;
1089 
1090 					RiColor(color);
1091 				}
1092 				|
1093 				RIB_OPACITY
1094 				RIB_FLOAT
1095 				RIB_FLOAT
1096 				RIB_FLOAT
1097 				{
1098 					RtColor	color;
1099 
1100 					color[0]	=	$2;
1101 					color[1]	=	$3;
1102 					color[2]	=	$4;
1103 
1104 					RiOpacity(color);
1105 				}
1106 				|
1107 				RIB_COLOR
1108 				RIB_ARRAY_BEGIN
1109 				RIB_FLOAT
1110 				RIB_FLOAT
1111 				RIB_FLOAT
1112 				RIB_ARRAY_END
1113 				{
1114 					RtColor	color;
1115 
1116 					color[0]	=	$3;
1117 					color[1]	=	$4;
1118 					color[2]	=	$5;
1119 
1120 					RiColor(color);
1121 				}
1122 				|
1123 				RIB_OPACITY
1124 				RIB_ARRAY_BEGIN
1125 				RIB_FLOAT
1126 				RIB_FLOAT
1127 				RIB_FLOAT
1128 				RIB_ARRAY_END
1129 				{
1130 					RtColor	color;
1131 
1132 					color[0]	=	$3;
1133 					color[1]	=	$4;
1134 					color[2]	=	$5;
1135 
1136 					RiOpacity(color);
1137 				}
1138 				|
1139 				RIB_TEXTURE_COORDINATES
1140 				RIB_FLOAT
1141 				RIB_FLOAT
1142 				RIB_FLOAT
1143 				RIB_FLOAT
1144 				RIB_FLOAT
1145 				RIB_FLOAT
1146 				RIB_FLOAT
1147 				RIB_FLOAT
1148 				{
1149 					RiTextureCoordinates($2,$3,$4,$5,$6,$7,$8,$9);
1150 				}
1151 				|
1152 				RIB_TEXTURE_COORDINATES
1153 				RIB_ARRAY_BEGIN
1154 				RIB_FLOAT
1155 				RIB_FLOAT
1156 				RIB_FLOAT
1157 				RIB_FLOAT
1158 				RIB_FLOAT
1159 				RIB_FLOAT
1160 				RIB_FLOAT
1161 				RIB_FLOAT
1162 				RIB_ARRAY_END
1163 				{
1164 					RiTextureCoordinates($3,$4,$5,$6,$7,$8,$9,$10);
1165 				}
1166 				|
1167 				RIB_LIGHT_SOURCE
1168 				RIB_TEXT
1169 				RIB_FLOAT
1170 				ribPL
1171 				{
1172 					TLight	*nLight	=	new TLight;
1173 					nLight->index	=	(int) $3;
1174 					nLight->name	=	NULL;
1175 					nLight->handle	=	RiLightSourceV($2,numParameters,tokens,vals);
1176 					nLight->next	=	lights;
1177 					lights			=	nLight;
1178 				}
1179 				|
1180 				RIB_LIGHT_SOURCE
1181 				RIB_TEXT
1182 				RIB_TEXT
1183 				ribPL
1184 				{
1185 					TLight	*nLight	=	new TLight;
1186 					nLight->index	=	0;
1187 					nLight->name	=	strdup($3);
1188 					nLight->handle	=	RiLightSourceV($2,numParameters,tokens,vals);
1189 					nLight->next	=	lights;
1190 					lights			=	nLight;
1191 				}
1192 				|
1193 				RIB_LIGHT_SOURCE
1194 				RIB_TEXT
1195 				ribPL
1196 				{
1197 					RiLightSourceV($2,numParameters,tokens,vals);
1198 				}
1199 				|
1200 				RIB_AREA_LIGHT_SOURCE
1201 				RIB_TEXT
1202 				RIB_FLOAT
1203 				ribPL
1204 				{
1205 					TLight	*nLight	=	new TLight;
1206 					nLight->index	=	(int) $3;
1207 					nLight->name	=	NULL;
1208 					nLight->handle	=	RiAreaLightSourceV($2,numParameters,tokens,vals);
1209 					nLight->next	=	lights;
1210 					lights			=	nLight;
1211 				}
1212 				|
1213 				RIB_AREA_LIGHT_SOURCE
1214 				RIB_TEXT
1215 				RIB_TEXT
1216 				ribPL
1217 				{
1218 					TLight	*nLight	=	new TLight;
1219 					nLight->index	=	0;
1220 					nLight->name	=	strdup($3);
1221 					nLight->handle	=	RiAreaLightSourceV($2,numParameters,tokens,vals);
1222 					nLight->next	=	lights;
1223 					lights			=	nLight;
1224 				}
1225 				|
1226 				RIB_ILLUMINATE
1227 				RIB_FLOAT
1228 				RIB_FLOAT
1229 				{
1230 					TLight	*cLight;
1231 
1232 					for (cLight=lights;cLight!=NULL;cLight=cLight->next)
1233 						if (cLight->index == (int) $2)	break;
1234 
1235 					if (cLight != NULL) {
1236 						RiIlluminate(cLight->handle,(int) $3);
1237 					} else {
1238 						error(CODE_RANGE,"The light %d is not found",(int) $2);
1239 					}
1240 				}
1241 				|
1242 				RIB_ILLUMINATE
1243 				RIB_TEXT
1244 				RIB_FLOAT
1245 				{
1246 					TLight	*cLight;
1247 
1248 					for (cLight=lights;cLight!=NULL;cLight=cLight->next)
1249 						if (cLight->name != NULL) {
1250 							if (strcmp(cLight->name,$2) == 0) break;
1251 						}
1252 
1253 					if (cLight != NULL) {
1254 						RiIlluminate(cLight->handle,(int) $3);
1255 					} else {
1256 						error(CODE_RANGE,"The light \"%s\" is not found",$2);
1257 					}
1258 				}
1259 				|
1260 				RIB_SURFACE
1261 				RIB_TEXT
1262 				ribPL
1263 				{
1264 					RiSurfaceV($2,numParameters,tokens,vals);
1265 				}
1266 				|
1267 				RIB_ATMOSPHERE
1268 				RIB_TEXT
1269 				ribPL
1270 				{
1271 					RiAtmosphereV($2,numParameters,tokens,vals);
1272 				}
1273 				|
1274 				RIB_INTERIOR
1275 				RIB_TEXT
1276 				ribPL
1277 				{
1278 					RiInteriorV($2,numParameters,tokens,vals);
1279 				}
1280 				|
1281 				RIB_EXTERIOR
1282 				RIB_TEXT
1283 				ribPL
1284 				{
1285 					RiExteriorV($2,numParameters,tokens,vals);
1286 				}
1287 				|
1288 				RIB_SHADING_RATE
1289 				RIB_FLOAT
1290 				{
1291 					RiShadingRate($2);
1292 				}
1293 				|
1294 				RIB_SHADING_INTERPOLATION
1295 				RIB_TEXT
1296 				{
1297 					RiShadingInterpolation($2);
1298 				}
1299 				|
1300 				RIB_MATTE
1301 				RIB_FLOAT
1302 				{
1303 					RiMatte((RtBoolean) $2);
1304 				}
1305 				|
1306 				RIB_BOUND
1307 				RIB_ARRAY_BEGIN
1308 				RIB_FLOAT
1309 				RIB_FLOAT
1310 				RIB_FLOAT
1311 				RIB_FLOAT
1312 				RIB_FLOAT
1313 				RIB_FLOAT
1314 				RIB_ARRAY_END
1315 				{
1316 					RtBound	bound;
1317 
1318 					bound[0]	=	$3;
1319 					bound[1]	=	$4;
1320 					bound[2]	=	$5;
1321 					bound[3]	=	$6;
1322 					bound[4]	=	$7;
1323 					bound[5]	=	$8;
1324 
1325 					RiBound(bound);
1326 				}
1327 				|
1328 				RIB_BOUND
1329 				RIB_FLOAT
1330 				RIB_FLOAT
1331 				RIB_FLOAT
1332 				RIB_FLOAT
1333 				RIB_FLOAT
1334 				RIB_FLOAT
1335 				{
1336 					RtBound	bound;
1337 
1338 					bound[0]	=	$2;
1339 					bound[1]	=	$3;
1340 					bound[2]	=	$4;
1341 					bound[3]	=	$5;
1342 					bound[4]	=	$6;
1343 					bound[5]	=	$7;
1344 
1345 					RiBound(bound);
1346 				}
1347 				|
1348 				RIB_DETAIL
1349 				RIB_ARRAY_BEGIN
1350 				RIB_FLOAT
1351 				RIB_FLOAT
1352 				RIB_FLOAT
1353 				RIB_FLOAT
1354 				RIB_FLOAT
1355 				RIB_FLOAT
1356 				RIB_ARRAY_END
1357 				{
1358 					RtBound	bound;
1359 
1360 					bound[0]	=	$3;
1361 					bound[1]	=	$4;
1362 					bound[2]	=	$5;
1363 					bound[3]	=	$6;
1364 					bound[4]	=	$7;
1365 					bound[5]	=	$8;
1366 
1367 					RiDetail(bound);
1368 				}
1369 				|
1370 				RIB_DETAIL
1371 				RIB_FLOAT
1372 				RIB_FLOAT
1373 				RIB_FLOAT
1374 				RIB_FLOAT
1375 				RIB_FLOAT
1376 				RIB_FLOAT
1377 				{
1378 					RtBound	bound;
1379 
1380 					bound[0]	=	$2;
1381 					bound[1]	=	$3;
1382 					bound[2]	=	$4;
1383 					bound[3]	=	$5;
1384 					bound[4]	=	$6;
1385 					bound[5]	=	$7;
1386 
1387 					RiDetail(bound);
1388 				}
1389 				|
1390 				RIB_DETAIL_RANGE
1391 				RIB_FLOAT
1392 				RIB_FLOAT
1393 				RIB_FLOAT
1394 				RIB_FLOAT
1395 				{
1396 					RiDetailRange($2,$3,$4,$5);
1397 				}
1398 				|
1399 				RIB_DETAIL_RANGE
1400 				RIB_ARRAY_BEGIN
1401 				RIB_FLOAT
1402 				RIB_FLOAT
1403 				RIB_FLOAT
1404 				RIB_FLOAT
1405 				RIB_ARRAY_END
1406 				{
1407 					RiDetailRange($3,$4,$5,$6);
1408 				}
1409 				|
1410 				RIB_GEOMETRIC_APPROXIMATION
1411 				RIB_TEXT
1412 				RIB_FLOAT
1413 				{
1414 					RiGeometricApproximation($2,$3);
1415 				}
1416 				|
1417 				RIB_GEOMETRIC_REPRESENTATION
1418 				RIB_TEXT
1419 				{
1420 					RiGeometricRepresentation($2);
1421 				}
1422 				|
1423 				RIB_ORIENTATION
1424 				RIB_TEXT
1425 				{
1426 					RiOrientation($2);
1427 				}
1428 				|
1429 				RIB_REVERSE_ORIENTATION
1430 				{
1431 					RiReverseOrientation();
1432 				}
1433 				|
1434 				RIB_SIDES
1435 				RIB_FLOAT
1436 				{
1437 					RiSides((int) $2);
1438 				}
1439 				|
1440 				RIB_IDENTITY
1441 				{
1442 					RiIdentity();
1443 				}
1444 				|
1445 				RIB_TRANSFORM
1446 				RIB_ARRAY_BEGIN
1447 				RIB_FLOAT
1448 				RIB_FLOAT
1449 				RIB_FLOAT
1450 				RIB_FLOAT
1451 				RIB_FLOAT
1452 				RIB_FLOAT
1453 				RIB_FLOAT
1454 				RIB_FLOAT
1455 				RIB_FLOAT
1456 				RIB_FLOAT
1457 				RIB_FLOAT
1458 				RIB_FLOAT
1459 				RIB_FLOAT
1460 				RIB_FLOAT
1461 				RIB_FLOAT
1462 				RIB_FLOAT
1463 				RIB_ARRAY_END
1464 				{
1465 					RtMatrix	tmp;
1466 
1467 					tmp[0][0]	=	$3;
1468 					tmp[0][1]	=	$4;
1469 					tmp[0][2]	=	$5;
1470 					tmp[0][3]	=	$6;
1471 					tmp[1][0]	=	$7;
1472 					tmp[1][1]	=	$8;
1473 					tmp[1][2]	=	$9;
1474 					tmp[1][3]	=	$10;
1475 					tmp[2][0]	=	$11;
1476 					tmp[2][1]	=	$12;
1477 					tmp[2][2]	=	$13;
1478 					tmp[2][3]	=	$14;
1479 					tmp[3][0]	=	$15;
1480 					tmp[3][1]	=	$16;
1481 					tmp[3][2]	=	$17;
1482 					tmp[3][3]	=	$18;
1483 
1484 					RiTransform(tmp);
1485 				}
1486 				|
1487 				RIB_CONCAT_TRANSFORM
1488 				RIB_ARRAY_BEGIN
1489 				RIB_FLOAT
1490 				RIB_FLOAT
1491 				RIB_FLOAT
1492 				RIB_FLOAT
1493 				RIB_FLOAT
1494 				RIB_FLOAT
1495 				RIB_FLOAT
1496 				RIB_FLOAT
1497 				RIB_FLOAT
1498 				RIB_FLOAT
1499 				RIB_FLOAT
1500 				RIB_FLOAT
1501 				RIB_FLOAT
1502 				RIB_FLOAT
1503 				RIB_FLOAT
1504 				RIB_FLOAT
1505 				RIB_ARRAY_END
1506 				{
1507 					RtMatrix	tmp;
1508 
1509 					tmp[0][0]	=	$3;
1510 					tmp[0][1]	=	$4	;
1511 					tmp[0][2]	=	$5;
1512 					tmp[0][3]	=	$6;
1513 					tmp[1][0]	=	$7;
1514 					tmp[1][1]	=	$8;
1515 					tmp[1][2]	=	$9;
1516 					tmp[1][3]	=	$10;
1517 					tmp[2][0]	=	$11;
1518 					tmp[2][1]	=	$12;
1519 					tmp[2][2]	=	$13;
1520 					tmp[2][3]	=	$14;
1521 					tmp[3][0]	=	$15;
1522 					tmp[3][1]	=	$16;
1523 					tmp[3][2]	=	$17;
1524 					tmp[3][3]	=	$18;
1525 
1526 					RiConcatTransform(tmp);
1527 				}
1528 				|
1529 				RIB_PERSPECTIVE
1530 				RIB_FLOAT
1531 				{
1532 					RiPerspective($2);
1533 				}
1534 				|
1535 				RIB_TRANSLATE
1536 				RIB_FLOAT
1537 				RIB_FLOAT
1538 				RIB_FLOAT
1539 				{
1540 					RiTranslate($2,$3,$4);
1541 				}
1542 				|
1543 				RIB_SCALE
1544 				RIB_FLOAT
1545 				RIB_FLOAT
1546 				RIB_FLOAT
1547 				{
1548 					RiScale($2,$3,$4);
1549 				}
1550 				|
1551 				RIB_ROTATE
1552 				RIB_FLOAT
1553 				RIB_FLOAT
1554 				RIB_FLOAT
1555 				RIB_FLOAT
1556 				{
1557 					RiRotate($2,$3,$4,$5);
1558 				}
1559 				|
1560 				RIB_SKEW
1561 				RIB_FLOAT
1562 				RIB_FLOAT
1563 				RIB_FLOAT
1564 				RIB_FLOAT
1565 				RIB_FLOAT
1566 				RIB_FLOAT
1567 				RIB_FLOAT
1568 				{
1569 					RiSkew($2,$3,$4,$5,$6,$7,$8);
1570 				}
1571 				|
1572 				RIB_SKEW
1573 				RIB_ARRAY_BEGIN
1574 				RIB_FLOAT
1575 				RIB_FLOAT
1576 				RIB_FLOAT
1577 				RIB_FLOAT
1578 				RIB_FLOAT
1579 				RIB_FLOAT
1580 				RIB_FLOAT
1581 				RIB_ARRAY_END
1582 				{
1583 					RiSkew($3,$4,$5,$6,$7,$8,$9);
1584 				}
1585 				|
1586 				RIB_DEFORMATION
1587 				RIB_TEXT
1588 				ribPL
1589 				{
1590 					RiDeformationV($2,numParameters,tokens,vals);
1591 				}
1592 				|
1593 				RIB_DISPLACEMENT
1594 				RIB_TEXT
1595 				ribPL
1596 				{
1597 					RiDisplacementV($2,numParameters,tokens,vals);
1598 				}
1599 				|
1600 				RIB_COORDINATE_SYSTEM
1601 				RIB_TEXT
1602 				{
1603 					RiCoordinateSystem($2);
1604 				}
1605 				|
1606 				RIB_COORDINATE_SYS_TRANSFORM
1607 				RIB_TEXT
1608 				{
1609 					RiCoordSysTransform($2);
1610 				}
1611 				|
1612 				RIB_TRANSFORM_BEGIN
1613 				{
1614 					RiTransformBegin();
1615 				}
1616 				|
1617 				RIB_TRANSFORM_END
1618 				{
1619 					RiTransformEnd();
1620 				}
1621 				|
1622 				RIB_ATTRIBUTE
1623 				RIB_TEXT
1624 				ribPL
1625 				{
1626 					if (parameterListCheck()) {
1627 						RiAttributeV($2,numParameters,tokens,vals);
1628 					}
1629 				}
1630 				|
1631 				RIB_POLYGON
1632 				ribPL
1633 				{
1634 					if (parameterListCheck()) {
1635 						if (sizeCheck(numVertex,0,0,1)) {
1636 							RiPolygonV(numVertex,numParameters,tokens,vals);
1637 						}
1638 					}
1639 				}
1640 				|
1641 				RIB_GENERAL_POLYGON
1642 				ribIntArray
1643 				ribPL
1644 				{
1645 					int		*argi	=	getInt(0);
1646 
1647 					if (parameterListCheck()) {
1648 						if (sizeCheck(numVertex,0,0,1)) {
1649 							RiGeneralPolygonV($2,argi,numParameters,tokens,vals);
1650 						}
1651 					}
1652 				}
1653 				|
1654 				RIB_POINTS_POLYGONS
1655 				ribIntArray
1656 				ribIntArray
1657 				ribPL
1658 				{
1659 					int	*argi1		=	getInt(0);
1660 					int	*argi2		=	getInt($2);
1661 					int	nvertices	=	0;
1662 					int	i;
1663 					int	maxVertex	=	0;
1664 
1665 
1666 					// Find out how many items are in verts array
1667 					for (i=0;i<$2;i++) {
1668 						nvertices	+=	argi1[i];
1669 					}
1670 
1671 					if (nvertices != $3) {
1672 						error(CODE_MISSINGDATA,"Vertex count mismatch (%d != %d)\n",nvertices,$3);
1673 					} else {
1674 						// Find out the number of vertices required
1675 						for (i=0,maxVertex=0;i<nvertices;i++) {
1676 							if (argi2[i] > maxVertex)
1677 								maxVertex	=	argi2[i];
1678 						}
1679 
1680 						maxVertex++;
1681 
1682 						if (parameterListCheck()) {
1683 							if (sizeCheck(maxVertex,0,nvertices,$2)) {
1684 								RiPointsPolygonsV($2,argi1,argi2,numParameters,tokens,vals);
1685 							}
1686 						}
1687 					}
1688 				}
1689 				|
1690 				RIB_POINTS_GENERAL_POLYGONS
1691 				ribIntArray
1692 				ribIntArray
1693 				ribIntArray
1694 				ribPL
1695 				{
1696 					int	*argi1		=	getInt(0);
1697 					int	*argi2		=	getInt($2);
1698 					int	*argi3		=	getInt($3+$2);
1699 					int	numvertices	=	0;
1700 					int	numloops	=	0;
1701 					int	maxVertex	=	0;
1702 					int	i;
1703 
1704 					for (i=0;i<$2;i++) {
1705 						numloops	+=	argi1[i];
1706 					}
1707 
1708 					if (numloops != $3) {
1709 						error(CODE_MISSINGDATA,"Loop count mismatch (%d != %d)\n",numloops,$3);
1710 					} else {
1711 						for (i=0;i<$3;i++) {
1712 							numvertices	+=	argi2[i];
1713 						}
1714 
1715 						if (numvertices != $4) {
1716 							error(CODE_MISSINGDATA,"Vertex count mismatch (%d != %d)\n",numvertices,$4);
1717 						} else {
1718 							for (i=0;i<numvertices;i++) {
1719 								if (argi3[i] > maxVertex)
1720 									maxVertex	=	argi3[i];
1721 							}
1722 
1723 							maxVertex++;
1724 
1725 							if (parameterListCheck()) {
1726 								if (sizeCheck(maxVertex,0,numvertices,$2)) {
1727 									RiPointsGeneralPolygonsV($2,argi1,argi2,argi3,numParameters,tokens,vals);
1728 								}
1729 							}
1730 						}
1731 					}
1732 				}
1733 				|
1734 				RIB_BASIS
1735 				RIB_TEXT
1736 				RIB_FLOAT
1737 				RIB_TEXT
1738 				RIB_FLOAT
1739 				{
1740 					RtBasis	*argf1,*argf2;
1741 
1742 					if ((getBasis(&argf1,$2)) && (getBasis(&argf2,$4))) {
1743 						RiBasis(argf1[0],(int) $3, argf2[0],(int) $5);
1744 					}
1745 				}
1746 				|
1747 				RIB_BASIS
1748 				RIB_ARRAY_BEGIN
1749 				RIB_FLOAT
1750 				RIB_FLOAT
1751 				RIB_FLOAT
1752 				RIB_FLOAT
1753 				RIB_FLOAT
1754 				RIB_FLOAT
1755 				RIB_FLOAT
1756 				RIB_FLOAT
1757 				RIB_FLOAT
1758 				RIB_FLOAT
1759 				RIB_FLOAT
1760 				RIB_FLOAT
1761 				RIB_FLOAT
1762 				RIB_FLOAT
1763 				RIB_FLOAT
1764 				RIB_FLOAT
1765 				RIB_ARRAY_END
1766 				RIB_FLOAT
1767 				RIB_TEXT
1768 				RIB_FLOAT
1769 				{
1770 					RtBasis	*argf2;
1771 
1772 					if (getBasis(&argf2,$21)) {
1773 						RtBasis	tmp;
1774 
1775 						tmp[0][0]	=	$3;
1776 						tmp[0][1]	=	$4;
1777 						tmp[0][2]	=	$5;
1778 						tmp[0][3]	=	$6;
1779 						tmp[1][0]	=	$7;
1780 						tmp[1][1]	=	$8;
1781 						tmp[1][2]	=	$9;
1782 						tmp[1][3]	=	$10;
1783 						tmp[2][0]	=	$11;
1784 						tmp[2][1]	=	$12;
1785 						tmp[2][2]	=	$13;
1786 						tmp[2][3]	=	$14;
1787 						tmp[3][0]	=	$15;
1788 						tmp[3][1]	=	$16;
1789 						tmp[3][2]	=	$17;
1790 						tmp[3][3]	=	$18;
1791 
1792 						RiBasis(tmp,(int) $20,argf2[0],(int) $22);
1793 					}
1794 				}
1795 				|
1796 				RIB_BASIS
1797 				RIB_TEXT
1798 				RIB_FLOAT
1799 				RIB_ARRAY_BEGIN
1800 				RIB_FLOAT
1801 				RIB_FLOAT
1802 				RIB_FLOAT
1803 				RIB_FLOAT
1804 				RIB_FLOAT
1805 				RIB_FLOAT
1806 				RIB_FLOAT
1807 				RIB_FLOAT
1808 				RIB_FLOAT
1809 				RIB_FLOAT
1810 				RIB_FLOAT
1811 				RIB_FLOAT
1812 				RIB_FLOAT
1813 				RIB_FLOAT
1814 				RIB_FLOAT
1815 				RIB_FLOAT
1816 				RIB_ARRAY_END
1817 				RIB_FLOAT
1818 				{
1819 					RtBasis	*argf1;
1820 
1821 					if (getBasis(&argf1,$2)) {
1822 						RtBasis	tmp;
1823 
1824 						tmp[0][0]	=	$5;
1825 						tmp[0][1]	=	$6;
1826 						tmp[0][2]	=	$7;
1827 						tmp[0][3]	=	$8;
1828 						tmp[1][0]	=	$9;
1829 						tmp[1][1]	=	$10;
1830 						tmp[1][2]	=	$11;
1831 						tmp[1][3]	=	$12;
1832 						tmp[2][0]	=	$13;
1833 						tmp[2][1]	=	$14;
1834 						tmp[2][2]	=	$15;
1835 						tmp[2][3]	=	$16;
1836 						tmp[3][0]	=	$17;
1837 						tmp[3][1]	=	$18;
1838 						tmp[3][2]	=	$19;
1839 						tmp[3][3]	=	$20;
1840 
1841 						RiBasis(argf1[0],(int) $3,tmp,(int) $22);
1842 					}
1843 				}
1844 				|
1845 				RIB_BASIS
1846 				RIB_ARRAY_BEGIN
1847 				RIB_FLOAT
1848 				RIB_FLOAT
1849 				RIB_FLOAT
1850 				RIB_FLOAT
1851 				RIB_FLOAT
1852 				RIB_FLOAT
1853 				RIB_FLOAT
1854 				RIB_FLOAT
1855 				RIB_FLOAT
1856 				RIB_FLOAT
1857 				RIB_FLOAT
1858 				RIB_FLOAT
1859 				RIB_FLOAT
1860 				RIB_FLOAT
1861 				RIB_FLOAT
1862 				RIB_FLOAT
1863 				RIB_ARRAY_END
1864 				RIB_FLOAT
1865 				RIB_ARRAY_BEGIN
1866 				RIB_FLOAT
1867 				RIB_FLOAT
1868 				RIB_FLOAT
1869 				RIB_FLOAT
1870 				RIB_FLOAT
1871 				RIB_FLOAT
1872 				RIB_FLOAT
1873 				RIB_FLOAT
1874 				RIB_FLOAT
1875 				RIB_FLOAT
1876 				RIB_FLOAT
1877 				RIB_FLOAT
1878 				RIB_FLOAT
1879 				RIB_FLOAT
1880 				RIB_FLOAT
1881 				RIB_FLOAT
1882 				RIB_ARRAY_END
1883 				RIB_FLOAT
1884 				{
1885 					RtBasis	b1,b2;
1886 
1887 					b1[0][0]	=	$3;
1888 					b1[0][1]	=	$4;
1889 					b1[0][2]	=	$5;
1890 					b1[0][3]	=	$6;
1891 					b1[1][0]	=	$7;
1892 					b1[1][1]	=	$8;
1893 					b1[1][2]	=	$9;
1894 					b1[1][3]	=	$10;
1895 					b1[2][0]	=	$11;
1896 					b1[2][1]	=	$12;
1897 					b1[2][2]	=	$13;
1898 					b1[2][3]	=	$14;
1899 					b1[3][0]	=	$15;
1900 					b1[3][1]	=	$16;
1901 					b1[3][2]	=	$17;
1902 					b1[3][3]	=	$18;
1903 
1904 					b2[0][0]	=	$22;
1905 					b2[0][1]	=	$23;
1906 					b2[0][2]	=	$24;
1907 					b2[0][3]	=	$25;
1908 					b2[1][0]	=	$26;
1909 					b2[1][1]	=	$27;
1910 					b2[1][2]	=	$28;
1911 					b2[1][3]	=	$29;
1912 					b2[2][0]	=	$30;
1913 					b2[2][1]	=	$31;
1914 					b2[2][2]	=	$32;
1915 					b2[2][3]	=	$33;
1916 					b2[3][0]	=	$34;
1917 					b2[3][1]	=	$35;
1918 					b2[3][2]	=	$36;
1919 					b2[3][3]	=	$37;
1920 
1921 					RiBasis(b1,(int) $20,b2,(int) $39);
1922 				}
1923 				|
1924 				RIB_PATCH
1925 				RIB_TEXT
1926 				ribPL
1927 				{
1928 					int	numExpectedVertices;
1929 					int	numExpectedPatches	=	1;
1930 
1931 
1932 					if (strcmp($2,RI_BILINEAR) == 0) {
1933 						numExpectedVertices	=	4;
1934 					} else if (strcmp($2,RI_BICUBIC) == 0) {
1935 						numExpectedVertices	=	16;
1936 					} else {
1937 						error(CODE_BADTOKEN,"Unknown patch type: \"%s\"\n",$2);
1938 						numExpectedVertices	=	0;
1939 					}
1940 
1941 					if (numExpectedVertices > 0) {
1942 						if (parameterListCheck()) {
1943 							if (sizeCheck(numExpectedVertices,4,4,1)) {
1944 								RiPatchV($2,numParameters,tokens,vals);
1945 							}
1946 						}
1947 					}
1948 				}
1949 				|
1950 				RIB_PATCH_MESH
1951 				RIB_TEXT
1952 				RIB_FLOAT
1953 				RIB_TEXT
1954 				RIB_FLOAT
1955 				RIB_TEXT
1956 				ribPL
1957 				{
1958 					int	numExpectedVertices;
1959 					int	numuPatches,numvPatches;
1960 					int	nu	=	(int) $3;
1961 					int	nv	=	(int) $5;
1962 					CAttributes	*attributes	=	CRenderer::context->getAttributes(FALSE);
1963 					int	uw,vw;
1964 					int	numVaryings;
1965 
1966 					if (strcmp($4,RI_PERIODIC) == 0) {
1967 						uw	=	TRUE;
1968 					} else {
1969 						uw	=	FALSE;
1970 					}
1971 
1972 					if (strcmp($6,RI_PERIODIC) == 0) {
1973 						vw	=	TRUE;
1974 					} else {
1975 						vw	=	FALSE;
1976 					}
1977 
1978 					if (strcmp($2,RI_BILINEAR) == 0) {
1979 						numExpectedVertices	=	nu*nv;
1980 
1981 						if (uw) {
1982 							numuPatches	=	nu;
1983 						} else {
1984 							numuPatches	=	nu-1;
1985 						}
1986 
1987 
1988 						if (vw) {
1989 							numvPatches	=	nv;
1990 						} else {
1991 							numvPatches	=	nv-1;
1992 						}
1993 
1994 						numVaryings		=	nu*nv;
1995 					} else if (strcmp($2,RI_BICUBIC) == 0) {
1996 						numExpectedVertices	=	nu*nv;
1997 
1998 						if (uw) {
1999 							numuPatches	=	nu / attributes->uStep;
2000 						} else {
2001 							numuPatches	=	(nu - 4) / attributes->uStep + 1;
2002 						}
2003 
2004 
2005 						if (vw) {
2006 							numvPatches	=	nv / attributes->vStep;
2007 						} else {
2008 							numvPatches	=	(nv - 4) / attributes->vStep + 1;
2009 						}
2010 
2011 						numVaryings		=	(numuPatches+1-uw)*(numvPatches+1-vw);
2012 					} else {
2013 						error(CODE_BADTOKEN,"Unknown patch type: \"%s\"\n",$2);
2014 						numExpectedVertices	=	0;
2015 					}
2016 
2017 					if (numExpectedVertices > 0) {
2018 						if (parameterListCheck()) {
2019 							if (sizeCheck(numExpectedVertices,numVaryings,numuPatches*numvPatches*4,numuPatches*numvPatches)) {
2020 								RiPatchMeshV($2,(int) $3,$4,(int) $5,$6,numParameters,tokens,vals);
2021 							}
2022 						}
2023 					}
2024 				}
2025 				|
2026 				RIB_NU_PATCH
2027 				RIB_FLOAT
2028 				RIB_FLOAT
2029 				ribFloatArray
2030 				RIB_FLOAT
2031 				RIB_FLOAT
2032 				RIB_FLOAT
2033 				RIB_FLOAT
2034 				ribFloatArray
2035 				RIB_FLOAT
2036 				RIB_FLOAT
2037 				ribPL
2038 				{
2039 					float	*argf1	=	getFloat(0);
2040 					float	*argf2	=	getFloat($4);
2041 
2042 					int		uPoints	=	(int) $2;
2043 					int		uOrder	=	(int) $3;
2044 					int		vPoints	=	(int) $7;
2045 					int		vOrder	=	(int) $8;
2046 
2047 					int		uPatches	=	uPoints - uOrder+1;
2048 					int		vPatches	=	vPoints - vOrder+1;
2049 
2050 					int		numExpectedVertices	=	uPoints*vPoints;
2051 
2052 					if (parameterListCheck()) {
2053 						if (sizeCheck(numExpectedVertices,(uPoints-uOrder+2)*(vPoints-vOrder+2),uPatches*vPatches*4,uPatches*vPatches)) {
2054 							RiNuPatchV((int) $2,(int) $3,argf1,$5,$6,(int) $7,(int) $8,argf2,$10,$11,numParameters,tokens,vals);
2055 						}
2056 					}
2057 				}
2058 				|
2059 				RIB_TRIM_CURVE
2060 				ribIntArray
2061 				ribIntArray
2062 				ribFloatArray
2063 				ribFloatArray
2064 				ribFloatArray
2065 				ribIntArray
2066 				ribFloatArray
2067 				ribFloatArray
2068 				ribFloatArray
2069 				{
2070 					int		*argi1	=	getInt(0);
2071 					int		*argi2	=	getInt($2);
2072 					float	*argf3	=	getFloat(0);
2073 					float	*argf4	=	getFloat($4);
2074 					float	*argf5	=	getFloat($5+$4);
2075 					int		*argi6	=	getInt($3+$2);
2076 					float	*argf7	=	getFloat($6+$5+$4);
2077 					float	*argf8	=	getFloat($8+$6+$5+$4);
2078 					float	*argf9	=	getFloat($9+$8+$6+$5+$4);
2079 
2080 					RiTrimCurve($2,argi1,argi2,argf3,argf4,argf5,argi6,argf7,argf8,argf9);
2081 				}
2082 				|
2083 				RIB_SPHERE
2084 				RIB_FLOAT
2085 				RIB_FLOAT
2086 				RIB_FLOAT
2087 				RIB_FLOAT
2088 				ribPL
2089 				{
2090 					if (parameterListCheck()) {
2091 						if (sizeCheck(0,4,4,1)) {
2092 							RiSphereV($2,$3,$4,$5,numParameters,tokens,vals);
2093 						}
2094 					}
2095 				}
2096 				|
2097 				RIB_SPHERE
2098 				RIB_ARRAY_BEGIN
2099 				RIB_FLOAT
2100 				RIB_FLOAT
2101 				RIB_FLOAT
2102 				RIB_FLOAT
2103 				RIB_ARRAY_END
2104 				ribPL
2105 				{
2106 					if (parameterListCheck()) {
2107 						if (sizeCheck(0,4,4,1)) {
2108 							RiSphereV($3,$4,$5,$6,numParameters,tokens,vals);
2109 						}
2110 					}
2111 				}
2112 				|
2113 				RIB_CONE
2114 				RIB_FLOAT
2115 				RIB_FLOAT
2116 				RIB_FLOAT
2117 				ribPL
2118 				{
2119 					if (parameterListCheck()) {
2120 						if (sizeCheck(0,4,4,1)) {
2121 							RiConeV($2,$3,$4,numParameters,tokens,vals);
2122 						}
2123 					}
2124 				}
2125 				|
2126 				RIB_CONE
2127 				RIB_ARRAY_BEGIN
2128 				RIB_FLOAT
2129 				RIB_FLOAT
2130 				RIB_FLOAT
2131 				RIB_ARRAY_END
2132 				ribPL
2133 				{
2134 					if (parameterListCheck()) {
2135 						if (sizeCheck(0,4,4,1)) {
2136 							RiConeV($3,$4,$5,numParameters,tokens,vals);
2137 						}
2138 					}
2139 				}
2140 				|
2141 				RIB_CYLINDER
2142 				RIB_FLOAT
2143 				RIB_FLOAT
2144 				RIB_FLOAT
2145 				RIB_FLOAT
2146 				ribPL
2147 				{
2148 					if (parameterListCheck()) {
2149 						if (sizeCheck(0,4,4,1)) {
2150 							RiCylinderV($2,$3,$4,$5,numParameters,tokens,vals);
2151 						}
2152 					}
2153 				}
2154 				|
2155 				RIB_CYLINDER
2156 				RIB_ARRAY_BEGIN
2157 				RIB_FLOAT
2158 				RIB_FLOAT
2159 				RIB_FLOAT
2160 				RIB_FLOAT
2161 				RIB_ARRAY_END
2162 				ribPL
2163 				{
2164 					if (parameterListCheck()) {
2165 						if (sizeCheck(0,4,4,1)) {
2166 							RiCylinderV($3,$4,$5,$6,numParameters,tokens,vals);
2167 						}
2168 					}
2169 				}
2170 				|
2171 				RIB_HYPERBOLOID
2172 				RIB_FLOAT
2173 				RIB_FLOAT
2174 				RIB_FLOAT
2175 				RIB_FLOAT
2176 				RIB_FLOAT
2177 				RIB_FLOAT
2178 				RIB_FLOAT
2179 				ribPL
2180 				{
2181 					if (parameterListCheck()) {
2182 						if (sizeCheck(0,4,4,1)) {
2183 							RtPoint	p1,p2;
2184 
2185 							p1[0]	=	$2;
2186 							p1[1]	=	$3;
2187 							p1[2]	=	$4;
2188 							p2[0]	=	$5;
2189 							p2[1]	=	$6;
2190 							p2[2]	=	$7;
2191 
2192 							RiHyperboloidV(p1,p2,$8,numParameters,tokens,vals);
2193 						}
2194 					}
2195 				}
2196 				|
2197 				RIB_HYPERBOLOID
2198 				RIB_ARRAY_BEGIN
2199 				RIB_FLOAT
2200 				RIB_FLOAT
2201 				RIB_FLOAT
2202 				RIB_FLOAT
2203 				RIB_FLOAT
2204 				RIB_FLOAT
2205 				RIB_FLOAT
2206 				RIB_ARRAY_END
2207 				ribPL
2208 				{
2209 					if (parameterListCheck()) {
2210 						if (sizeCheck(0,4,4,1)) {
2211 							RtPoint	p1,p2;
2212 
2213 							p1[0]	=	$3;
2214 							p1[1]	=	$4;
2215 							p1[2]	=	$5;
2216 							p2[0]	=	$6;
2217 							p2[1]	=	$7;
2218 							p2[2]	=	$8;
2219 
2220 							RiHyperboloidV(p1,p2,$9,numParameters,tokens,vals);
2221 						}
2222 					}
2223 				}
2224 				|
2225 				RIB_PARABOLOID
2226 				RIB_FLOAT
2227 				RIB_FLOAT
2228 				RIB_FLOAT
2229 				RIB_FLOAT
2230 				ribPL
2231 				{
2232 					if (parameterListCheck()) {
2233 						if (sizeCheck(0,4,4,1)) {
2234 							RiParaboloidV($2,$3,$4,$5,numParameters,tokens,vals);
2235 						}
2236 					}
2237 				}
2238 				|
2239 				RIB_PARABOLOID
2240 				RIB_ARRAY_BEGIN
2241 				RIB_FLOAT
2242 				RIB_FLOAT
2243 				RIB_FLOAT
2244 				RIB_FLOAT
2245 				RIB_ARRAY_END
2246 				ribPL
2247 				{
2248 					if (parameterListCheck()) {
2249 						if (sizeCheck(0,4,4,1)) {
2250 							RiParaboloidV($3,$4,$5,$6,numParameters,tokens,vals);
2251 						}
2252 					}
2253 				}
2254 				|
2255 				RIB_DISK
2256 				RIB_FLOAT
2257 				RIB_FLOAT
2258 				RIB_FLOAT
2259 				ribPL
2260 				{
2261 					if (parameterListCheck()) {
2262 						if (sizeCheck(0,4,4,1)) {
2263 							RiDiskV($2,$3,$4,numParameters,tokens,vals);
2264 						}
2265 					}
2266 				}
2267 				|
2268 				RIB_DISK
2269 				RIB_ARRAY_BEGIN
2270 				RIB_FLOAT
2271 				RIB_FLOAT
2272 				RIB_FLOAT
2273 				RIB_ARRAY_END
2274 				ribPL
2275 				{
2276 					if (parameterListCheck()) {
2277 						if (sizeCheck(0,4,4,1)) {
2278 							RiDiskV($3,$4,$5,numParameters,tokens,vals);
2279 						}
2280 					}
2281 				}
2282 				|
2283 				RIB_TORUS
2284 				RIB_FLOAT
2285 				RIB_FLOAT
2286 				RIB_FLOAT
2287 				RIB_FLOAT
2288 				RIB_FLOAT
2289 				ribPL
2290 				{
2291 					if (parameterListCheck()) {
2292 						if (sizeCheck(0,4,4,1)) {
2293 							RiTorusV($2,$3,$4,$5,$6,numParameters,tokens,vals);
2294 						}
2295 					}
2296 				}
2297 				|
2298 				RIB_TORUS
2299 				RIB_ARRAY_BEGIN
2300 				RIB_FLOAT
2301 				RIB_FLOAT
2302 				RIB_FLOAT
2303 				RIB_FLOAT
2304 				RIB_FLOAT
2305 				RIB_ARRAY_END
2306 				ribPL
2307 				{
2308 					if (parameterListCheck()) {
2309 						if (sizeCheck(0,4,4,1)) {
2310 							RiTorusV($3,$4,$5,$6,$7,numParameters,tokens,vals);
2311 						}
2312 					}
2313 				}
2314 				|
2315 				RIB_CURVES
2316 				RIB_TEXT
2317 				ribIntArray
2318 				RIB_TEXT
2319 				ribPL
2320 				{
2321 					int			*argi1		=	getInt(0);
2322 					int			numVertices,numUniforms;
2323 					CAttributes	*attributes	=	CRenderer::context->getAttributes(FALSE);
2324 					int			wrap;
2325 					int			numVaryings,i;
2326 
2327 					if (strcmp($4,RI_PERIODIC) == 0) {
2328 						wrap	=	TRUE;
2329 					} else {
2330 						wrap	=	FALSE;
2331 					}
2332 
2333 					if (strcmp($2,RI_LINEAR) == 0) {
2334 						for (i=0,numVertices=0;i<$3;i++) {
2335 							numVertices	+=	argi1[i];
2336 						}
2337 
2338 						numVaryings		=	numVertices;
2339 						numUniforms		=	$3;
2340 					} else if (strcmp($2,RI_CUBIC) == 0) {
2341 						for (i=0,numVertices=0,numVaryings=0,numUniforms=0;i<$3;i++) {
2342 							int	j		=	(argi1[i] - 4) / attributes->vStep + 1;
2343 							numVertices	+=	argi1[i];
2344 							numVaryings	+=	j + (1 - wrap);
2345 						}
2346 						numUniforms		=	$3;
2347 					} else {
2348 						error(CODE_BADTOKEN,"Unknown patch type: \"%s\"\n",$2);
2349 						numVertices	=	0;
2350 					}
2351 
2352 					if (numVertices > 0) {
2353 						if (parameterListCheck()) {
2354 							if (sizeCheck(numVertices,numVaryings,0,numUniforms)) {
2355 								RiCurvesV($2,$3,argi1,$4,numParameters,tokens,vals);
2356 							}
2357 						}
2358 					}
2359 				}
2360 				|
2361 				RIB_POINTS
2362 				ribPL
2363 				{
2364 					if (parameterListCheck()) {
2365 						if (sizeCheck(numVertex,0,0,1)) {
2366 							RiPointsV(numVertex,numParameters,tokens,vals);
2367 						}
2368 					}
2369 				}
2370 				|
2371 				RIB_SUBDIVISION_MESH
2372 				RIB_TEXT
2373 				ribIntArray
2374 				ribIntArray
2375 				ribTextArray
2376 				ribIntArray
2377 				ribIntArray
2378 				ribFloatArray
2379 				ribPL
2380 				{
2381 					int			*argi1,*argi2,*argi3,*argi4;
2382 					const char	**args1;
2383 					float		*argf1;
2384 					int			numVertices,i,j;
2385 
2386 					if (parameterListCheck()) {
2387 						argi1	=	getInt(0);
2388 						argi2	=	getInt($3);
2389 						args1	=	getString(0);
2390 						argi3	=	getInt($3+$4);
2391 						argi4	=	getInt($3+$4+$6);
2392 						argf1	=	getFloat(0);
2393 
2394 						// Count the number of faces / vertices
2395 						for (i=0,j=0;i<$3;j+=argi1[i],i++);
2396 
2397 						for (numVertices=-1,i=0;i<j;i++) {
2398 							if (argi2[i] > numVertices)	numVertices	=	argi2[i];
2399 						}
2400 						numVertices++;
2401 
2402 
2403 						if (sizeCheck(numVertices,numVertices,j,$3)) {
2404 							RiSubdivisionMeshV($2,$3,argi1,argi2,$5,args1,argi3,argi4,argf1,numParameters,tokens,vals);
2405 						}
2406 					}
2407 				}
2408 				|
2409 				RIB_SUBDIVISION_MESH
2410 				RIB_TEXT
2411 				ribIntArray
2412 				ribIntArray
2413 				ribIntArray
2414 				ribIntArray
2415 				ribIntArray
2416 				ribFloatArray
2417 				ribPL
2418 				{
2419 					// Support for no tags (parsed as int array for arg 5)
2420 					int			*argi1,*argi2,*argi3,*argi4;
2421 					const char	**args1;
2422 					float		*argf1;
2423 					int			numVertices,i,j;
2424 
2425 					if (parameterListCheck()) {
2426 						argi1	=	getInt(0);
2427 						argi2	=	getInt($3);
2428 						args1	=	getString(0);
2429 						argi3	=	getInt($3+$4);
2430 						argi4	=	getInt($3+$4+$6);
2431 						argf1	=	getFloat(0);
2432 
2433 						if ($5 == 0) {
2434 							// Count the number of faces / vertices
2435 							for (i=0,j=0;i<$3;j+=argi1[i],i++);
2436 
2437 							for (numVertices=-1,i=0;i<j;i++) {
2438 								if (argi2[i] > numVertices)	numVertices	=	argi2[i];
2439 							}
2440 							numVertices++;
2441 
2442 
2443 							if (sizeCheck(numVertices,numVertices,j,$3)) {
2444 								RiSubdivisionMeshV($2,$3,argi1,argi2,0,args1,argi3,argi4,argf1,numParameters,tokens,vals);
2445 							}
2446 						} else {
2447 							error(CODE_BADTOKEN,"Subdivision surface expected string array (tags) for argument 5\n");
2448 						}
2449 					}
2450 				}
2451 				/* REMOVED for non-standard
2452 				|
2453 				RIB_SUBDIVISION_MESH
2454 				RIB_TEXT
2455 				ribIntArray
2456 				ribIntArray
2457 				ribPL
2458 				{
2459 					int		*argi1,*argi2;
2460 					int		numVertices,i,j;
2461 
2462 					if (parameterListCheck()) {
2463 						argi1	=	getInt(0);
2464 						argi2	=	getInt($3);
2465 
2466 						// Count the number of faces / vertices
2467 						for (i=0,j=0;i<$3;j+=argi1[i],i++);
2468 
2469 						for (numVertices=-1,i=0;i<j;i++) {
2470 							if (argi2[i] > numVertices)	numVertices	=	argi2[i];
2471 						}
2472 						numVertices++;
2473 
2474 
2475 						if (sizeCheck(numVertices,numVertices,j,$3)) {
2476 							RiSubdivisionMeshV($2,$3,argi1,argi2,0,NULL,NULL,NULL,NULL,numParameters,tokens,vals);
2477 						}
2478 					}
2479 				}
2480 				*/
2481 				|
2482 				RIB_BLOBBY
2483 				RIB_FLOAT
2484 				ribIntArray
2485 				ribFloatArray
2486 				ribPL
2487 				{
2488 					// FIXME: Not implemented
2489 				}
2490 				|
2491 				RIB_BLOBBY
2492 				RIB_FLOAT
2493 				ribIntArray
2494 				ribFloatArray
2495 				ribTextArray
2496 				ribPL
2497 				{
2498 					// FIXME: Not implemented
2499 				}
2500 				|
2501 				RIB_GEOMETRY
2502 				RIB_TEXT
2503 				ribPL
2504 				{
2505 					if (parameterListCheck()) {
2506 						RiGeometryV($2,numParameters,tokens,vals);
2507 					}
2508 				}
2509 				|
2510 				RIB_PROCEDURAL
2511 				RIB_TEXT
2512 				ribTextArray
2513 				RIB_ARRAY_BEGIN
2514 				RIB_FLOAT
2515 				RIB_FLOAT
2516 				RIB_FLOAT
2517 				RIB_FLOAT
2518 				RIB_FLOAT
2519 				RIB_FLOAT
2520 				RIB_ARRAY_END
2521 				{
2522 					RtBound			bound;
2523 					CDelayedData	*cData	=	new CDelayedData;
2524 					const char		**arg;
2525 
2526 					bound[0]	=	$5;
2527 					bound[1]	=	$6;
2528 					bound[2]	=	$7;
2529 					bound[3]	=	$8;
2530 					bound[4]	=	$9;
2531 					bound[5]	=	$10;
2532 
2533 					cData->bmin[COMP_X]	=	$5;
2534 					cData->bmax[COMP_X]	=	$6;
2535 
2536 					cData->bmin[COMP_Y]	=	$7;
2537 					cData->bmax[COMP_Y]	=	$8;
2538 
2539 					cData->bmin[COMP_Z]	=	$9;
2540 					cData->bmax[COMP_Z]	=	$10;
2541 
2542 					if (strcmp($2,RI_PROCDELAYEDREADARCHIVE) == 0) {
2543 						if ($3 != 1) {
2544 							error(CODE_MISSINGDATA,"Procedure delayed archive expects one argument (given %d)\n",$3);
2545 						} else {
2546 							arg		=	getString(0);
2547 
2548 							cData->generator	=	strdup(arg[0]);
2549 
2550 							RiProcedural(cData,bound,RiProcDelayedReadArchive,RiProcFree);
2551 						}
2552 					} else if (strcmp($2,RI_PROCRUNPROGRAM) == 0) {
2553 						if ($3 != 2) {
2554 							error(CODE_MISSINGDATA,"Procedure run program expects two arguments (given %d)\n",$3);
2555 						} else {
2556 							arg		=	getString(0);
2557 
2558 							cData->generator	=	strdup(arg[0]);
2559 							cData->helper		=	strdup(arg[1]);
2560 
2561 							RiProcedural(cData,bound,RiProcRunProgram,RiProcFree);
2562 						}
2563 					} else if (strcmp($2,RI_PROCDYNAMICLOAD) == 0) {
2564 						if ($3 != 2) {
2565 							error(CODE_MISSINGDATA,"Procedure dynamic load expects two arguments (given %d)\n",$3);
2566 						} else {
2567 							arg		=	getString(0);
2568 
2569 							cData->generator	=	strdup(arg[0]);
2570 							cData->helper		=	strdup(arg[1]);
2571 
2572 							RiProcedural(cData,bound,RiProcDynamicLoad,RiProcFree);
2573 						}
2574 					} else {
2575 						error(CODE_BADTOKEN,"Unknown procedural: %s\n",$2);
2576 						delete cData;
2577 					}
2578 				}
2579 				|
2580 				RIB_SOLID_BEGIN
2581 				RIB_TEXT
2582 				{
2583 					RiSolidBegin($2);
2584 				}
2585 				|
2586 				RIB_SOLID_END
2587 				{
2588 					RiSolidEnd();
2589 				}
2590 				|
2591 				RIB_OBJECT_BEGIN
2592 				RIB_FLOAT
2593 				{
2594 					TObject	*nObject	=	new TObject;
2595 
2596 					nObject->handle		=	RiObjectBegin();
2597 					nObject->index		=	(int) $2;
2598 					nObject->name		=	NULL;
2599 					nObject->next		=	objects;
2600 					objects				=	nObject;
2601 				}
2602 				|
2603 				RIB_OBJECT_BEGIN
2604 				RIB_TEXT
2605 				{
2606 					TObject	*nObject	=	new TObject;
2607 
2608 					nObject->handle		=	RiObjectBegin();
2609 					nObject->index		=	-1;
2610 					nObject->name		=	strdup($2);
2611 					nObject->next		=	objects;
2612 					objects				=	nObject;
2613 				}
2614 				|
2615 				RIB_OBJECT_END
2616 				{
2617 					RiObjectEnd();
2618 				}
2619 				|
2620 				RIB_OBJECT_INSTANCE
2621 				RIB_FLOAT
2622 				{
2623 					TObject	*cObject;
2624 
2625 					for (cObject=objects;cObject!=NULL;cObject=cObject->next) {
2626 						if (cObject->index == (int) $2)	break;
2627 					}
2628 
2629 					if (cObject != NULL) {
2630 						RiObjectInstance(cObject->handle);
2631 					} else {
2632 						error(CODE_MISSINGDATA,"Object %d is not found\n",(int) $2);
2633 					}
2634 				}
2635 				|
2636 				RIB_OBJECT_INSTANCE
2637 				RIB_TEXT
2638 				{
2639 					TObject	*cObject;
2640 
2641 					for (cObject=objects;cObject!=NULL;cObject=cObject->next) {
2642 						if (strcmp(cObject->name,$2) == 0)	break;
2643 					}
2644 
2645 					if (cObject != NULL) {
2646 						RiObjectInstance(cObject->handle);
2647 					} else {
2648 						error(CODE_MISSINGDATA,"Object \"%s\" is not found\n",$2);
2649 					}
2650 				}
2651 				|
2652 				RIB_MOTION_BEGIN
2653 				ribFloats
2654 				{
2655 					float	*argf	=	getFloat(0);
2656 
2657 					RiMotionBeginV($2,argf);
2658 				}
2659 				|
2660 				RIB_MOTION_END
2661 				{
2662 					RiMotionEnd();
2663 				}
2664 				|
2665 				RIB_MAKE_TEXTURE
2666 				RIB_TEXT
2667 				RIB_TEXT
2668 				RIB_TEXT
2669 				RIB_TEXT
2670 				RIB_TEXT
2671 				RIB_FLOAT
2672 				RIB_FLOAT
2673 				ribPL
2674 				{
2675 					RtFilterFunc	f;
2676 
2677 					if ((f		=	getFilter($6)) != NULL)  {
2678 						RiMakeTextureV($2,$3,$4,$5,f,$7,$8,numParameters,tokens,vals);
2679 					}
2680 				}
2681 				|
2682 				RIB_MAKE_BRICKMAP
2683 				ribTextArray
2684 				RIB_TEXT
2685 				ribPL
2686 				{
2687 					RiMakeBrickMapV($2,getString(0),$3,numParameters,tokens,vals);
2688 				}
2689 				|
2690 				RIB_MAKE_BUMP
2691 				RIB_TEXT
2692 				RIB_TEXT
2693 				RIB_TEXT
2694 				RIB_TEXT
2695 				RIB_TEXT
2696 				RIB_FLOAT
2697 				RIB_FLOAT
2698 				ribPL
2699 				{
2700 					RtFilterFunc	f;
2701 
2702 					if ((f		=	getFilter($6)) != NULL) {
2703 						RiMakeBumpV($2,$3,$4,$5,f,$7,$8,numParameters,tokens,vals);
2704 					}
2705 				}
2706 				|
2707 				RIB_MAKE_LAT_LONG_ENVIRONMENT
2708 				RIB_TEXT
2709 				RIB_TEXT
2710 				RIB_TEXT
2711 				RIB_FLOAT
2712 				RIB_FLOAT
2713 				ribPL
2714 				{
2715 					RtFilterFunc	f;
2716 
2717 					if ((f		=	getFilter($4)) != NULL) {
2718 						RiMakeLatLongEnvironmentV($2,$3,f,$5,$6,numParameters,tokens,vals);
2719 					}
2720 				}
2721 				|
2722 				RIB_MAKE_CUBE_FACE_ENVIRONMENT
2723 				RIB_TEXT
2724 				RIB_TEXT
2725 				RIB_TEXT
2726 				RIB_TEXT
2727 				RIB_TEXT
2728 				RIB_TEXT
2729 				RIB_TEXT
2730 				RIB_FLOAT
2731 				RIB_TEXT
2732 				RIB_FLOAT
2733 				RIB_FLOAT
2734 				ribPL
2735 				{
2736 					RtFilterFunc	f;
2737 
2738 					if ((f =	getFilter($10)) != NULL) {
2739 						RiMakeCubeFaceEnvironmentV($2,$3,$4,$5,$6,$7,$8,$9,f,$11,$12,numParameters,tokens,vals);
2740 					}
2741 				}
2742 				|
2743 				RIB_MAKE_SHADOW
2744 				RIB_TEXT
2745 				RIB_TEXT
2746 				ribPL
2747 				{
2748 					RiMakeShadowV($2,$3,numParameters,tokens,vals);
2749 				}
2750 				|
2751 				RIB_ARCHIVE_BEGIN
2752 				RIB_TEXT
2753 				ribPL
2754 				{
2755 					RiArchiveBeginV($2,numParameters,tokens,vals);
2756 				}
2757 				|
2758 				RIB_ARCHIVE_END
2759 				{
2760 					RiArchiveEnd();
2761 				}
2762 				|
2763 				RIB_RESOURCE_BEGIN
2764 				{
2765 					RiResourceBegin();
2766 				}
2767 				|
2768 				RIB_RESOURCE_END
2769 				{
2770 					RiResourceEnd();
2771 				}
2772 				|
2773 				RIB_RESOURCE
2774 				RIB_TEXT
2775 				RIB_TEXT
2776 				ribPL
2777 				{
2778 					RiResourceV($2,$3,numParameters,tokens,vals);
2779 				}
2780 				|
2781 				RIB_IFBEGIN
2782 				RIB_TEXT
2783 				ribPL
2784 				{
2785 					RiIfBeginV($2,numParameters,tokens,vals);
2786 				}
2787 				|
2788 				RIB_IFEND
2789 				{
2790 					RiIfEnd();
2791 				}
2792 				|
2793 				RIB_ELSEIF
2794 				RIB_TEXT
2795 				ribPL
2796 				{
2797 					RiElseIfV($2,numParameters,tokens,vals);
2798 				}
2799 				|
2800 				RIB_ELSE
2801 				{
2802 					RiElse();
2803 				}
2804 				|
2805 				RIB_ERROR_HANDLER
2806 				RIB_TEXT
2807 				{
2808 					RtErrorHandler 	e	=	getErrorHandler($2);
2809 
2810 					if (e != NULL) {
2811 						RiErrorHandler(e);
2812 					}
2813 				}
2814 				|
2815 				RIB_VERSION
2816 				RIB_FLOAT
2817 				{
2818 				}
2819 				|
2820 				RIB_VERSION
2821 				RIB_VERSION_STRING
2822 				{
2823 				}
2824 				|
2825 				error
2826 				{
2827 					if (YYRECOVERING() == 0) {
2828 						error(CODE_BADFILE,"Syntax error\n");
2829 					}
2830 				}
2831 				;
2832 
2833 %%
2834 
2835 #include "lex.rib.cpp"
2836 
2837 // Our position in the rib file
2838 static	int		ribStart	=	0;
2839 static	int		ribStep		=	5*(1<<10);	// Parse 5 KB at a time
2840 
2841 ///////////////////////////////////////////////////////////////////////
2842 // Function				:	riberror
2843 // Description			:	Parser error file
2844 // Return Value			:	-
2845 // Comments				:
riberror(const char * s,...)2846 void	riberror(const char *s,...) {
2847 	warning(CODE_BADFILE,"RIB Parse error\n");
2848 }
2849 
2850 ///////////////////////////////////////////////////////////////////////
2851 // Function				:	ribParse
2852 // Description			:	Parse a rib file
2853 // Return Value			:	-
2854 // Comments				:
ribParse(const char * fileName,void (* c)(const char *,...))2855 void	ribParse(const char *fileName,void (*c)(const char *,...)) {
2856 
2857 
2858 	if (fileName != NULL) {
2859 
2860 
2861 		// Save the environment first
2862 		TLight				*savedLights						=	lights;
2863 		TObject				*savedObjects						=	objects;
2864 		int					savedRibLineno						=	ribLineno;
2865 		void				(*savedCallback)(const char *,...)	=	callback;
2866 		int					savedNumParameters					=	numParameters;
2867 		int					savedMaxParameter					=	maxParameter;
2868 		TParameter			*savedParameters					=	parameters;
2869 		RtToken				*savedTokens						=	tokens;
2870 		RtPointer			*savedVals							=	vals;
2871 		int					savedRibDepth						=	ribDepth;
2872 		YY_BUFFER_STATE		savedLexState						=	YY_CURRENT_BUFFER;
2873 		TRibFile			*savedRibStack						=	ribStack;
2874 		const char			*savedRibFile						=	ribFile;
2875 		FILE				*savedRibIn							=	ribin;
2876 
2877 		// Guard against the depreciated fdopen on windoze
2878 #ifdef _WINDOWS
2879 #define fdopen _fdopen
2880 #endif
2881 
2882 		// Init the environment
2883 		if (fileName[0] == '-') {
2884 			// Read from stdin
2885 #ifdef HAVE_ZLIB
2886 			ribin			=	(FILE *) gzdopen(fileno(stdin),"rb");
2887 #else
2888 			ribin			=	stdin;
2889 #endif
2890 		} else if (fileName[0] == '|') {
2891 			// Read from an arbitrary stream
2892 #ifdef HAVE_ZLIB
2893 			ribin			=	(FILE *) gzdopen(atoi(fileName+1),"rb");
2894 #else
2895 			ribin			=	fdopen(atoi(fileName+1),"r");
2896 #endif
2897 		} else {
2898 			// Read from file
2899 #ifdef HAVE_ZLIB
2900 			ribin			=	(FILE *) gzopen(fileName,"rb");
2901 #else
2902 			ribin			=	fopen(fileName,"r");
2903 #endif
2904 		}
2905 
2906 		lights				=	NULL;
2907 		objects				=	NULL;
2908 		callback			=	c;
2909 		maxParameter		=	20;
2910 		numParameters		=	0;
2911 		parameters			=	new TParameter[maxParameter];
2912 		tokens				=	new RtToken[maxParameter];
2913 		vals				=	new RtPointer[maxParameter];
2914 
2915 		if ( ribDepth++ == 0) {
2916 			// outhermost
2917 		} else {
2918 			// create a new lex buffer and switch to it
2919 
2920 			// Note: there are two stacking methods here,
2921 			//  one is explicitly handled when lexing for ReadArchive
2922 			//	the other uses the return stack (and increments ribDepth)
2923 
2924 			rib_switch_to_buffer(rib_create_buffer( ribin, YY_BUF_SIZE ) );
2925 			ribStack		=	NULL;	// prevent falling out of current ReadArchive
2926 		}
2927 
2928 		ribFile				=	fileName;
2929 		ribLineno			=	1;
2930 
2931 		// Put a checkpoint in the global memory
2932 		// This checkpoint is restored after every RIB command
2933 		memSave(memoryCheckpoint,CRenderer::globalMemory);
2934 
2935 		// Parse the RIB
2936 		ribparse();
2937 
2938 		// Restore the memory to the latest checkpoint
2939 		memRestore(memoryCheckpoint,CRenderer::globalMemory);
2940 
2941 		if (ribin != NULL) {
2942 #ifdef HAVE_ZLIB
2943 			gzclose((gzFile)ribin);
2944 #else
2945 			fclose(ribin);
2946 #endif
2947 		}
2948 
2949 		// Clear the lights
2950 		TLight	*cLight;
2951 		while((cLight=lights) != NULL) {
2952 			lights	=	lights->next;
2953 			if (cLight->name != NULL)	free(cLight->name);
2954 			delete cLight;
2955 		}
2956 
2957 		// Clear the objects
2958 		TObject	*cObject;
2959 		while((cObject=objects) != NULL) {
2960 			objects	=	objects->next;
2961 			if (cObject->name != NULL)	free(cObject->name);
2962 			delete cObject;
2963 		}
2964 
2965 		// Clear the parameters
2966 		delete [] parameters;
2967 		delete [] tokens;
2968 		delete [] vals;
2969 
2970 
2971 		ribin				=	savedRibIn;
2972 		ribFile				=	savedRibFile;
2973 		tokens				=	savedTokens;
2974 		vals				=	savedVals;
2975 		parameters			=	savedParameters;
2976 		numParameters		=	savedNumParameters;
2977 		maxParameter		=	savedMaxParameter;
2978 		lights				=	savedLights;
2979 		objects				=	savedObjects;
2980 		ribLineno			=	savedRibLineno;
2981 		callback			=	savedCallback;
2982 
2983 		if ((ribDepth = savedRibDepth) == 0) {
2984 			// outhermost
2985 		} else {
2986 			// We're done parsing an inner level, switch the lex buffer back
2987 
2988 			rib_delete_buffer( YY_CURRENT_BUFFER );
2989 			rib_switch_to_buffer( savedLexState );
2990 
2991 			ribStack 		= 	savedRibStack;
2992 		}
2993 	}
2994 }
2995 
2996 
2997 
2998 ///////////////////////////////////////////////////////////////////////
2999 // Function				:	parserCleanup
3000 // Description			:	Clean the memory allocated by the parser
3001 // Return Value			:	-
3002 // Comments				:
parserCleanup()3003 void		parserCleanup() {
3004 	rib_delete_buffer(YY_CURRENT_BUFFER);
3005 	yy_init				= 1;
3006 }
3007 
3008