1 %option prefix="vs10_"
2 
3 %x INCLUDE DEFINE DEFSTR DEFSPACE SKIPLINE EATCOMMENT EATSTRING SAVELINE
4 %x MACRONAME MACROBODY MACROPARM EATMACRO EATDEFINE MODIFIER MACROPARMSTART
5 %x IFDEFNAME IFDEFBODY ENDMACRO MACROPARMEND
6 
7 %{
8 
9 #include <stdarg.h>
10 #include <stdlib.h>
11 #ifdef _WIN32
12 #include <io.h>
13 #  ifdef __GNUC__
14 #    include <sys/types.h>
15 #    include <ctype.h>
16 #  endif
17 #else
18 #include <sys/types.h>
19 #include <ctype.h>
20 #define _stat stat
21 #define _open open
22 #define _O_RDONLY O_RDONLY
23 #define _fstat fstat
24 #define _close close
25 #define stricmp strcasecmp
26 
27 #endif
28 #include <sys/stat.h>
29 #include <fcntl.h>
30 #include <string.h>
31 #include "macro.h"
32 #include "nvparse_errors.h"
33 #include "vs1.0_inst_list.h"
34 #include "_vs1.0_parser.h"
35 #define yylineno line_number
36 #include "nvparse_externs.h"
37 #define YY_NO_UNPUT
38 
39 int line_incr;
40 void LexError(const char *format, ...);
41 void LexWarning(const char *format, ...);
42 char *ReadTextFile(const char * filename);
43 
44 unsigned int MakeRegisterMask(char *findName);
45 unsigned int FindSwizzleValue(char *swizzleText);
46 
47 
48 enum ERROR_VALUES {
49 	ERROR_NONE = 0,
50 	ERROR_MEMORY_ALLOC,
51 	ERROR_FILE_OPEN,
52 	ERROR_UNSUCCESSFUL_ASSEMBLE,
53 	ERROR_TOO_MANY_PARMS,
54 	ERROR_DEST_WRITE,
55 	ERROR_LIST_OPEN,
56 	ERROR_DEST_OPEN,
57 	ERROR_NO_ARGUMENTS,
58 	ERROR_MACRO_OVERRUN
59 };
60 
61 
62 
63 //extern void GenSwitchFileNames(char *fileName);
64 //extern unsigned int gLinesAssembled;
65 unsigned int gLinesAssembled;
66 
67 #define YY_INPUT(buf,result,max_size) \
68 { \
69 	int c = *myin++; \
70 	result = (c == 0) ? YY_NULL : (buf[0] = c, 1); \
71 }
72 
73 #define SAFEDELETEARRAY(x) if ((x) != NULL) \
74 						delete [] (x)
75 #define SAFEFREE(x) if ((x) != NULL) \
76 						free((x))
77 
78 #define MAXREPLACESTRING 255
79 
80 char gReplaceText[MAXREPLACESTRING+1];
81 
82 //
83 // forward prototypes for macro functions
84 //
85 void MacroIncFunction(char *, unsigned int *, char **);
86 void MacroDecFunction(char *, unsigned int *, char **);
87 void MacroAddFunction(char *, unsigned int *, char **);
88 void MacroSubFunction(char *, unsigned int *, char **);
89 
90 MACROFUNCTIONS gMacroFunctions[] = {
91 	{ "inc(", MacroIncFunction },
92 	{ "dec(", MacroDecFunction },
93 	{ "add(", MacroAddFunction },
94 	{ "sub(", MacroSubFunction }
95 };
96 
97 #define NUM_MACRO_FUNCTIONS (sizeof(gMacroFunctions) / sizeof(MACROFUNCTIONS))
98 
99 #define MAX_INCLUDE_DEPTH 1024
100 typedef struct INCLUDEINFO
101 {
102 	char	*fileName;
103 	unsigned int lineNo;
104 	YY_BUFFER_STATE buffer;
105 	MACROENTRY *lastInvokeMacro;				// save off in case nested macros.
106 	MACROENTRY *lastParseMacro;				// recursive macros
107 	MACROTEXT *lastMacroLineParse;			// save off for recursive lines of macros working on.
108 	bool lastbInsideMacro;					// save off for recursive macros
109 	bool lastbInsideDefine;					// save off for recursive macros/defines
110 	bool lastbInsideInclude;
111 	bool lastbProcessingIFDEF; 				// save off #define information
112 //	FILE *fileHandle;
113 	char *prevString;
114 	char *nextString;
115 } INCLUDEINFO;
116 
117 INCLUDEINFO gIncludeStack[MAX_INCLUDE_DEPTH];
118 int gIncludeStackIndex = 0;
119 
120 IFDEFINFO gIfDefStack[MAX_IFDEF_DEPTH];
121 int gIfDefStackIndex = 0;
122 
123 unsigned int &base_linenumber = gIncludeStack[0].lineNo;
124 
125 bool gbInsideInclude = false;
126 bool gbProcessingBuiltIn = false;
127 bool gbProcessingDefine = false;
128 unsigned int gCountParen = 0;
129 
130 bool gbProcessingIFDEF = false;
131 bool gbIFDEF = false;
132 bool gbCompareDefine = false;
133 unsigned int gIfDefStartLine;
134 
135 
136 MACROENTRY *gLastMacro;
137 MACROENTRY *gInvokeMacro;
138 MACROENTRY *gTempMacro;					// until all the parameters are read
139 MACROENTRY *FindMacro(char *macroName);
140 MACROENTRY *FindNMacro(char *macroName, unsigned int sLen);
141 
142 MACROFUNCTIONPTR gMacroCallFunction;
143 
144 const char *builtInMacros =	"macro m3x2 reg1, reg2, reg3\n"
145 						"	dp3	%reg1.x, %reg2, %reg3\n"
146 						"	dp3 %reg1.y, %reg2, %inc(%reg3)\n"
147 						"endm";
148 
149 //
150 // local prototypes
151 //
152 void CleanUp();
153 void ReplaceMacroParms(char *srcLine, char *destLine,
154 							MACROENTRY *srcParms, MACROENTRY *invParms);
155 
156 MACROTEXT *SaveMacroText(char *srcText, MACROTEXT *lastMacroText);
157 void FreeMacroEntry(MACROENTRY *macEntry);
158 void EndMacroParms();
159 char *FindAlphaNum(char *srcStr, unsigned int *sLen);
160 void DebugUnhandledState();
161 
162 
163 unsigned int gCommentStartLine;
164 unsigned int gMacroStartLine;
165 
166 char *gCurFileName = NULL;
167 
168 #define MAXSAVELINE 4095
169 
170 char gSaveLine[MAXSAVELINE+1];
171 char gMacroLine[MAXSAVELINE+1];
172 
173 #if 1
174 #ifdef _DEBUG
175 #define ECHO DebugUnhandledState();
176 #else
177 #define ECHO
178 #endif
179 #endif
180 
181 bool gbInsideMacro = false;		// flag if we are doing a macro replace or not.
182 bool gbTempInsideMacro = false;
183 unsigned int gInvokeState = INITIAL;
184 
185 
186 MACROENTRY *gParseMacro;		// which source macro entry we are using
187 MACROENTRY *gTempParseMacro;	// temporary holder until parameters are received.
188 MACROTEXT *gMacroLineParse;		// which line we are currently parsing inside the macro invocation
189 
190 enum OPCODETYPE
191 {
192 	TYPE_NONE = 0,
193 	TYPE_VERTEX_SHADER = 1,
194 	TYPE_PIXEL_SHADER = 2
195 };
196 typedef struct OPCODEMAP
197 {
198 	const char *string;				// string for opcode
199 	int tokenName;              // name of the corresponding token
200 	int numArguments;			// number of arguments for opcode
201 	float version;				// minimum version supported in.
202 	int opcodeTypeFlags;		// whether opcode can be used in vertex shader or pixel shader
203 	bool opcodeModify;			// if opcode modifiers can be used
204 	bool textureOpcode;			// only outputs to the texture unit
205 } OPCODEMAP;
206 
207 #ifndef TRUE
208 #define TRUE true
209 #endif
210 #ifndef FALSE
211 #define FALSE false
212 #endif
213 
214 OPCODEMAP theOpcodes[] = {
215 	{ "add",  ADD_INSTR, 3, 1.0f, TYPE_VERTEX_SHADER | TYPE_PIXEL_SHADER, TRUE, FALSE },
216 	{ "dp3",  DP3_INSTR, 3, 1.0f, TYPE_VERTEX_SHADER | TYPE_PIXEL_SHADER, TRUE, FALSE },
217 	{ "dp4",  DP4_INSTR, 3, 1.0f, TYPE_VERTEX_SHADER, FALSE, FALSE },
218 	{ "dst",  DST_INSTR, 3, 1.0f, TYPE_VERTEX_SHADER, FALSE, FALSE },
219 	{ "exp",  EXP_INSTR, 2, 1.0f, TYPE_VERTEX_SHADER, FALSE, FALSE },
220 	{ "expp", EXPP_INSTR, 2, 1.0f, TYPE_VERTEX_SHADER, FALSE, FALSE },
221 	{ "frc",  FRC_INSTR, 2, 1.0f, TYPE_VERTEX_SHADER, FALSE, FALSE },
222 	{ "lit",  LIT_INSTR, 2, 1.0f, TYPE_VERTEX_SHADER, FALSE, FALSE },
223 	{ "log",  LOG_INSTR, 2, 1.0f, TYPE_VERTEX_SHADER, FALSE, FALSE },
224 	{ "logp", LOGP_INSTR, 2, 1.0f, TYPE_VERTEX_SHADER, FALSE, FALSE },
225 	{ "m3x2", M3X2_INSTR, 3, 1.0f, TYPE_VERTEX_SHADER, FALSE, FALSE },
226 	{ "m3x3", M3X3_INSTR, 3, 1.0f, TYPE_VERTEX_SHADER, FALSE, FALSE },
227 	{ "m3x4", M3X4_INSTR, 3, 1.0f, TYPE_VERTEX_SHADER, FALSE, FALSE },
228 	{ "m4x3", M4X3_INSTR, 3, 1.0f, TYPE_VERTEX_SHADER, FALSE, FALSE },
229 	{ "m4x4", M4X4_INSTR, 3, 1.0f, TYPE_VERTEX_SHADER, FALSE, FALSE },
230 	{ "mad",  MAD_INSTR, 4, 1.0f, TYPE_VERTEX_SHADER | TYPE_PIXEL_SHADER, TRUE, FALSE },
231 	{ "max",  MAX_INSTR, 3, 1.0f, TYPE_VERTEX_SHADER, FALSE, FALSE },
232 	{ "min",  MIN_INSTR, 3, 1.0f, TYPE_VERTEX_SHADER, FALSE, FALSE },
233 	{ "mov",  MOV_INSTR, 2, 1.0f, TYPE_VERTEX_SHADER | TYPE_PIXEL_SHADER, TRUE, FALSE },
234 	{ "mul",  MUL_INSTR, 3, 1.0f, TYPE_VERTEX_SHADER | TYPE_PIXEL_SHADER, TRUE, FALSE },
235 	{ "nop",  NOP_INSTR, 0, 1.0f, TYPE_VERTEX_SHADER | TYPE_PIXEL_SHADER, TRUE, FALSE },
236 	{ "rcp",  RCP_INSTR, 2, 1.0f, TYPE_VERTEX_SHADER, FALSE, FALSE },
237 	{ "rsq",  RSQ_INSTR, 2, 1.0f, TYPE_VERTEX_SHADER, FALSE, FALSE },
238 	{ "sge",  SGE_INSTR, 3, 1.0f, TYPE_VERTEX_SHADER, FALSE, FALSE },
239 	{ "slt",  SLT_INSTR, 3, 1.0f, TYPE_VERTEX_SHADER, FALSE, FALSE },
240 	{ "sub",  SUB_INSTR, 3, 1.0f, TYPE_VERTEX_SHADER | TYPE_PIXEL_SHADER, TRUE, FALSE },
241 };
242 
243 #define NUMOPCODES (sizeof(theOpcodes) / sizeof(OPCODEMAP))
244 OPCODEMAP *FindOpcode(char *findName);
245 
246 
247 %}
248 
249 digits	([0-9]+)
250 digit	([0-9])
251 pt	"."
252 sign		[+-]?
253 exponent	([eE]{sign}{digits})
254 alpha [a-zA-Z_]
255 alphadigs [a-zA-Z0-9_]
256 notAlphaDigs ([^a-zA-Z0-9_])
257 
258 identifier		{alpha}{alphadigs}*
259 
260 
261 %%
262 
263 <SAVELINE>.*\n {
264 	gbProcessingDefine = false;
265 	gSaveLine[0] = '\0';
266 	strncat(gSaveLine, yytext, MAXSAVELINE);
267 //	GenDebugLine();
268 	if (gbProcessingIFDEF && (gbCompareDefine != gbIFDEF))
269 	{
270 		BEGIN(IFDEFBODY);
271 	}
272 	else
273 	{
274 		BEGIN(INITIAL);
275 	}
276 	yyless(0);
277 }
278 
279 <SAVELINE>.* {
280 	gbProcessingDefine = false;
281 	gSaveLine[0] = '\0';
282 	strncat(gSaveLine, yytext, MAXSAVELINE);
283 //	GenDebugLine();
284 	if (gbProcessingIFDEF && (gbCompareDefine != gbIFDEF))
285 	{
286 		BEGIN(IFDEFBODY);
287 	}
288 	else
289 	{
290 		BEGIN(INITIAL);
291 	}
292 	yyless(0);
293 }
294 
295 a{digits}[ \t]*[\n]?	{
296 //	fprintf( stderr, "%s", yytext );
297 	vs10_lval.reg.type = TYPE_ADDRESS_REG;
298 	vs10_lval.reg.index = atoi(&yytext[1]);
299 	if ( yytext[yyleng-1] == '\n' )
300 		line_incr = 1;
301 	return REGISTER;
302 }
303 
304 v{digits}[ \t]*[\n]?	{
305 //	fprintf( stderr, "%s", yytext );
306 	vs10_lval.reg.type = TYPE_VERTEX_ATTRIB_REG;
307 	vs10_lval.reg.index = atoi(&yytext[1]);
308 	if ( yytext[yyleng-1] == '\n' )
309 		line_incr = 1;
310 	return REGISTER;
311 }
312 
313 r{digits}[ \t]*[\n]?	{
314 //	fprintf( stderr, "%s", yytext );
315 	vs10_lval.reg.type = TYPE_TEMPORARY_REG;
316 	vs10_lval.reg.index = atoi(&yytext[1]);
317 	if ( yytext[yyleng-1] == '\n' )
318 		line_incr = 1;
319 	return REGISTER;
320 }
321 
322 c{digits}[ \t]*[\n]?	{
323 //	fprintf( stderr, "%s", yytext );
324 	vs10_lval.reg.type = TYPE_CONSTANT_MEM_REG;
325 	vs10_lval.reg.index = atoi(&yytext[1]);
326 	if ( yytext[yyleng-1] == '\n' )
327 		line_incr = 1;
328 	return REGISTER;
329 }
330 
331 oT{digits}[ \t]*[\n]?	{
332 //	fprintf( stderr, "%s", yytext );
333 	vs10_lval.reg.type = TYPE_TEXTURE_RESULT_REG;
334 	vs10_lval.reg.index = atoi(&yytext[2]);
335 	if ( yytext[yyleng-1] == '\n' )
336 		line_incr = 1;
337 	return REGISTER;
338 }
339 
340 oD{digits}[ \t]*[\n]?	{
341 //	fprintf( stderr, "%s", yytext );
342 	vs10_lval.reg.type = TYPE_COLOR_RESULT_REG;
343 	vs10_lval.reg.index = atoi(&yytext[2]);
344 	if ( yytext[yyleng-1] == '\n' )
345 		line_incr = 1;
346 	return REGISTER;
347 }
348 
349 oFog[ \t]*[\n]?	{
350 //	fprintf( stderr, "%s", yytext );
351 	vs10_lval.reg.type = TYPE_FOG_RESULT_REG;
352 	if ( yytext[yyleng-1] == '\n' )
353 		line_incr = 1;
354 	return REGISTER;
355 }
356 
357 oPos[ \t]*[\n]?	{
358 //	fprintf( stderr, "%s", yytext );
359 	vs10_lval.reg.type = TYPE_POSITION_RESULT_REG;
360 	if ( yytext[yyleng-1] == '\n' )
361 		line_incr = 1;
362 	return REGISTER;
363 }
364 
365 oPts[ \t]*[\n]?	{
366 //	fprintf( stderr, "%s", yytext );
367 	vs10_lval.reg.type = TYPE_POINTS_RESULT_REG;
368 	if ( yytext[yyleng-1] == '\n' )
369 		line_incr = 1;
370 	return REGISTER;
371 }
372 
373 [a-zA-Z][a-zA-Z0-9]+[ \t\n_] {
374 
375 	unsigned int offset;
376 
377     offset = strcspn(yytext, " \t\n_");
378 	yyless(offset);
379 
380 	OPCODEMAP *opcodeMap = FindOpcode(yytext);
381 	if ( opcodeMap != NULL )
382 	{
383 //		fprintf( stderr, "%s\t", opcodeMap->string );
384 		return( opcodeMap->tokenName );
385 	}
386 	else
387 	{
388 		gTempParseMacro = FindMacro(yytext);
389 
390 		if (gTempParseMacro != NULL)
391 		{
392 			if (gIncludeStackIndex >= MAX_INCLUDE_DEPTH )
393 			{
394 				LexError("macros nested too deeply");
395 				exit( 1 );
396 			}
397 
398 			if (gTempParseMacro->firstMacroLines != NULL)
399 			{
400 
401 				gTempMacro = (MACROENTRY *)malloc(sizeof(MACROENTRY));
402 				if (gTempMacro == NULL)
403 				{
404 					LexError("Out of memory allocating MACROENTRY structure.\n");
405 				}
406 				else
407 				{
408 
409 					gTempMacro->next = NULL;
410 					gTempMacro->prev = NULL;
411 					gTempMacro->macroName = NULL;
412 					gTempMacro->firstMacroParms = NULL;
413 					gTempMacro->lastMacroParms = NULL;
414 					gTempMacro->firstMacroLines = NULL;
415 					gTempMacro->lastMacroLines = NULL;
416 					gTempMacro->numParms = 0;
417 					gTempMacro->nLines = 0;
418 
419 					gbTempInsideMacro = true;		// flag we are currently doing a macro replace.
420 					gInvokeState = YYSTATE;
421 					if (gTempParseMacro->numParms > 0)
422 					{
423 						BEGIN(MACROPARMSTART);
424 					}
425 					else
426 					{
427 						EndMacroParms();
428 						gbTempInsideMacro = false;	// no longer waiting for macro invocation
429 					}
430 
431 
432 				}
433 			}
434 		}
435 		else
436 		{
437 //			fprintf( stderr, "Opcode: \"%s\" not found\n", yytext );
438 			REJECT;
439 		}
440 	}
441 
442 	//unsigned int offset;
443 	//
444 	//INSTRMAP *opcodeMap;
445 	//
446 	//offset = strcspn(yytext, " \t\n_");
447 	//yyless(offset);
448 	//opcodeMap = FindInstruction(yytext);
449 	//if (opcodeMap == NULL)
450 	//{
451 	//	REJECT;
452 	//}
453 	//
454 	//yylval.opcodeInfo.opcodeMap = opcodeMap;
455 	//
456 	//return OPCODE;
457 }
458 
459 
460 ";".*  {
461 //	fprintf( stderr, "%s", yytext );
462 	char *cmt = new char[yyleng+1];
463 	strncpy( cmt, yytext, yyleng );
464 	cmt[0] = '#';
465 	cmt[yyleng] = '\0';
466 	vs10_lval.comment = cmt;
467 	return COMMENT;
468 }
469 
470 "//".* {
471 //	fprintf( stderr, "%s", yytext );
472 	char *cmt = new char[yyleng+1];
473 	strncpy( cmt+1, yytext+1, yyleng-1 );
474 	cmt[0] = '#';
475 	cmt[1] = ' ';
476 	cmt[yyleng] = '\0';
477 	vs10_lval.comment = cmt;
478 	return COMMENT;
479 }
480 
481 "+"[ \t]*\n {
482 	fprintf( stderr, "COISSUE found\n" );
483 	yyless(yyleng-1);
484 	//return COISSUE;
485 }
486 
487 ^[ \t]*"+"[ \t]* {
488 	fprintf( stderr, "COISSUE found\n" );
489 	//return COISSUE;
490 }
491 
492 <INITIAL,MACROBODY>"/*" {
493 	gCommentStartLine = yylineno;
494 	yyless(0);
495 	BEGIN(EATCOMMENT);
496 }
497 
498 "#include"[ \t]+ {
499 	BEGIN(INCLUDE);
500 }
501 
502 <INCLUDE>[^ \t].*\n {	/* got the include file name */
503 
504 //	FILE *newyyin;
505 char *newyyin;
506 	char incFileName[1024];
507 	unsigned long sLen;
508 	bool validFileName;
509 
510 	if ( gIncludeStackIndex >= MAX_INCLUDE_DEPTH )
511 	{
512 		LexError("Includes nested too deeply, aborting\n");
513 		exit( 1 );
514 	}
515 
516 //	GenDebugLine();
517 //	GenListString();
518 	yylineno++;
519 	gLinesAssembled++;
520 
521 	validFileName = true;
522 	// zap "" and <>
523 	if ((yytext[0] == '"') || (yytext[0] == '<'))
524 	{
525 		char *endQuote;
526 		endQuote = strchr(&yytext[1], yytext[0]);
527 		sLen = (endQuote - yytext)-1;
528 		if (endQuote == NULL)
529 		{
530 			LexError("Unable to open include file %s\n", incFileName);
531 			BEGIN(INITIAL);
532 			validFileName = false;
533 		}
534 		else
535 		{
536 			incFileName[0] ='\0';
537 			strncat(incFileName, &yytext[1], sLen);
538 		}
539 	}
540 	else
541 	{
542 		strcpy(incFileName, yytext);
543 	}
544 
545 	if (validFileName)
546 	{
547 		sLen = strlen(incFileName);
548 		if ((incFileName[sLen-1] == '"') || (incFileName[sLen-1] == '>'))
549 		{
550 			incFileName[sLen-1] = '\0';
551 		}
552 
553 
554 		newyyin = ReadTextFile( incFileName );
555 //		newyyin = fopen( incFileName, "r" );
556 
557 		if ( ! newyyin )
558 		{
559 			LexError("Unable to open include file %s\n", incFileName);
560 			BEGIN(SAVELINE);
561 		}
562 		else
563 		{
564 			gIncludeStack[gIncludeStackIndex].fileName = gCurFileName;
565 			gIncludeStack[gIncludeStackIndex].lineNo = yylineno;
566 //			gIncludeStack[gIncludeStackIndex].fileHandle = yyin;
567 			gIncludeStack[gIncludeStackIndex].prevString = myin;
568 			gIncludeStack[gIncludeStackIndex].nextString = newyyin;
569 			gIncludeStack[gIncludeStackIndex].lastInvokeMacro = gInvokeMacro;
570 			gIncludeStack[gIncludeStackIndex].lastParseMacro = gParseMacro;
571 			gIncludeStack[gIncludeStackIndex].lastMacroLineParse = gMacroLineParse;
572 			gIncludeStack[gIncludeStackIndex].lastbInsideMacro = gbInsideMacro;
573 			gIncludeStack[gIncludeStackIndex].lastbInsideInclude = gbInsideInclude;
574 			gIncludeStack[gIncludeStackIndex].buffer = YY_CURRENT_BUFFER;
575 			gIncludeStack[gIncludeStackIndex].lastbProcessingIFDEF = gbProcessingIFDEF;
576 			gIncludeStackIndex++;
577 
578 			gbProcessingIFDEF = false;
579 
580 			gCurFileName = strdup(incFileName);
581 //			yyin = newyyin;
582 			myin = newyyin;
583 
584 //			GenSwitchFileNames(gCurFileName);
585 
586 			yylineno = 1;
587 
588 			yy_switch_to_buffer(yy_create_buffer( yyin, YY_BUF_SIZE ) );
589 
590 			gbInsideInclude = true;
591 
592 			BEGIN(SAVELINE);
593 		}
594 	}
595 }
596 
597 <EATCOMMENT><<EOF>> {
598 	LexError("End of file reached before end of comment started on line %d.\n", gCommentStartLine);
599 	BEGIN(INITIAL);
600 }
601 
602 <EATCOMMENT>.*\n {
603 	char *endComment;
604 	unsigned int keepSize;
605 
606 	strcpy(gSaveLine, yytext);
607 	endComment = strstr(yytext, "*/");
608 
609 	char *cmt;
610 	if (endComment != NULL)
611 	{
612 		keepSize = (endComment - yytext+2);
613 		yyless(keepSize);
614 		BEGIN(INITIAL);
615 
616 		if ( yytext[0] == '/' && yytext[1] == '*' )
617 		{
618 			cmt = new char[yyleng];
619 			strncpy( cmt+3, yytext+2, yyleng-2 );
620 			cmt[0] = '#';
621 			cmt[1] = ' ';
622 			cmt[2] = ' ';
623 			cmt[yyleng-1] = '\0';
624 		}
625 		else
626 		{
627 			cmt = new char[yyleng];
628 			strncpy( cmt+1, yytext, yyleng-2 );
629 			cmt[0] = '#';
630 			cmt[yyleng-1] = '\0';
631 		}
632 		vs10_lval.comment = cmt;
633 		return COMMENT;
634 	}
635 	else
636 	{
637 //		GenDebugLine();
638 //		GenListString();
639 		gLinesAssembled++;
640 		yylineno++;
641 
642 		if ( yytext[0] == '/' && yytext[1] == '*' )
643 		{
644 			cmt = new char[yyleng+2];
645 			strncpy( cmt+3, yytext+2, yyleng-2 );
646 			cmt[0] = '#';
647 			cmt[1] = ' ';
648 			cmt[2] = ' ';
649 			cmt[yyleng+1] = '\0';
650 		}
651 		else
652 		{
653 			cmt = new char[yyleng+2];
654 			strncpy( cmt+1, yytext, yyleng );
655 			cmt[0] = '#';
656 			cmt[yyleng+1] = '\0';
657 		}
658 		vs10_lval.comment = cmt;
659 		return COMMENT;
660 	}
661 }
662 
663 <DEFSTR><<EOF>> {
664 	LexError("#define was incomplete before end of file\n");
665 	BEGIN(INITIAL);
666 }
667 
668 <DEFINE><<EOF>> {
669 	LexError("#define was incomplete before end of file\n");
670 	BEGIN(INITIAL);
671 }
672 
673 <DEFSPACE><<EOF>> {
674 	LexError("#define was incomplete before end of file\n");
675 	BEGIN(INITIAL);
676 }
677 
678 <INCLUDE><<EOF>> {
679 	LexError("#include was incomplete before end of file\n");
680 	BEGIN(INITIAL);
681 }
682 
683 <MACROBODY><<EOF>> {
684 	LexError("End of file reached before end of #define or endm was found, macro started on line %d.\n", gMacroStartLine);
685 	BEGIN(INITIAL);
686 }
687 
688 <IFDEFBODY><<EOF>> {
689 	LexError("End of file reached before #endif found, macro started on line %d.\n", gIfDefStartLine);
690 	BEGIN(INITIAL);
691 }
692 
693 <DEFSTR>\n {
694 	LexError("#define was incomplete before end of line\n");
695 	BEGIN(SAVELINE);
696 //	GenDebugLine();
697 //	GenListString();
698 	gLinesAssembled++;
699 	yylineno++;
700 }
701 
702 <DEFINE>\n {
703 	LexError("#define was incomplete before end of line\n");
704 	BEGIN(SAVELINE);
705 //	GenDebugLine();
706 //	GenListString();
707 	gLinesAssembled++;
708 	yylineno++;
709 }
710 
711 <DEFSPACE>\n {
712 	LexError("#define was incomplete before end of line\n");
713 	BEGIN(SAVELINE);
714 //	GenDebugLine();
715 //	GenListString();
716 	gLinesAssembled++;
717 	yylineno++;
718 }
719 
720 "#ifdef"[ \t]+ {
721 	if (gIfDefStackIndex >= MAX_IFDEF_DEPTH)
722 	{
723 		LexError("Out of stack space for #ifdef, aborting.\n");
724 		exit( 1 );
725 	}
726 	else
727 	{
728 		gIfDefStack[gIfDefStackIndex].lastbProcessingIFDEF = gbProcessingIFDEF;
729 		gIfDefStack[gIfDefStackIndex].lastbIFDEF = gbIFDEF;
730 		gIfDefStack[gIfDefStackIndex].lastbCompareDefine = gbCompareDefine;
731 		gIfDefStack[gIfDefStackIndex].lastIfDefStartLine = gIfDefStartLine;
732 		gIfDefStackIndex++;
733 		gIfDefStartLine = yylineno;
734 
735 		gbCompareDefine = true;
736 		BEGIN(IFDEFNAME);
737 	}
738 }
739 
740 "#ifndef"[ \t]+ {
741 	if (gIfDefStackIndex >= MAX_IFDEF_DEPTH)
742 	{
743 		LexError("Out of stack space for #ifdef, aborting.\n");
744 		exit( 1 );
745 	}
746 	else
747 	{
748 		gIfDefStack[gIfDefStackIndex].lastbProcessingIFDEF = gbProcessingIFDEF;
749 		gIfDefStack[gIfDefStackIndex].lastbIFDEF = gbIFDEF;
750 		gIfDefStack[gIfDefStackIndex].lastbCompareDefine = gbCompareDefine;
751 		gIfDefStack[gIfDefStackIndex].lastIfDefStartLine = gIfDefStartLine;
752 		gIfDefStackIndex++;
753 		gIfDefStartLine = yylineno;
754 
755 		gbCompareDefine = false;
756 		BEGIN(IFDEFNAME);
757 	}
758 }
759 
760 <INITIAL,IFDEFBODY>"#else"[ \t]*((";"|"//").*)* {
761 	if (!gbProcessingIFDEF)
762 	{
763 		LexError("Unexpected #else found at line %d, skipping.\n", yylineno);
764 	}
765 	else
766 	{
767 		gbCompareDefine = !gbCompareDefine;
768 		BEGIN(INITIAL);
769 	}
770 }
771 
772 <IFDEFNAME>.*\n {
773 	char *defineName;
774 	unsigned int sLen;
775 
776 
777 	defineName = FindAlphaNum(yytext, &sLen);
778 	if (defineName == NULL)
779 	{
780 		defineName = strdup(yytext);
781 		defineName[yyleng-1] = '\0';	// kill \n
782 		LexWarning("Mangled name (%s) for #ifdef, assuming not defined.\n", defineName);
783 		free(defineName);
784 		gbIFDEF = false;
785 	}
786 	else
787 	{
788 		if (FindNMacro(defineName, sLen) != NULL)
789 		{
790 			gbIFDEF = true;
791 		}
792 		else
793 		{
794 			gbIFDEF = false;
795 		}
796 	}
797 
798 	gbProcessingIFDEF = true;
799 	if (gbIFDEF != gbCompareDefine)
800 	{
801 		BEGIN(IFDEFBODY);
802 	}
803 	else
804 	{
805 		BEGIN(SAVELINE);
806 	}
807 
808 //	GenDebugLine();
809 //	GenListString();
810 	gLinesAssembled++;
811 	yylineno++;
812 }
813 
814 <INITIAL,IFDEFBODY>[ \t]*"#endif"[ \t]*((";"|"//").*)* {
815 	if (!gbProcessingIFDEF)
816 	{
817 		LexError("Unexpected #endif found at line %d, skipping.\n", yylineno);
818 	}
819 	else
820 	{
821 		gIfDefStackIndex--;
822 		gbProcessingIFDEF = gIfDefStack[gIfDefStackIndex].lastbProcessingIFDEF;
823 		gbIFDEF = gIfDefStack[gIfDefStackIndex].lastbIFDEF;
824 		gbCompareDefine = gIfDefStack[gIfDefStackIndex].lastbCompareDefine;
825 		gIfDefStartLine = gIfDefStack[gIfDefStackIndex].lastIfDefStartLine;
826 
827 	}
828 
829 	if (YYSTATE == IFDEFBODY)
830 	{
831 		strncpy(gSaveLine, yytext, MAXSAVELINE);
832 	}
833 
834 	BEGIN(ENDMACRO);
835 
836 }
837 
838 <ENDMACRO>.* {
839 	LexWarning("Garbage at end of #endif or endm will be ignored.\n");
840 }
841 
842 <ENDMACRO>\n {
843 	BEGIN(SAVELINE);
844 	return '\n';
845 }
846 
847 <ENDMACRO><<EOF>> {
848 	BEGIN(INITIAL);
849 }
850 
851 <IFDEFBODY>.* {
852 	// eat line, because we are not in a TRUE #ifdef, or FALSE #ifndef
853 	strncpy(gSaveLine, yytext, MAXSAVELINE);
854 }
855 
856 <IFDEFBODY>\n {
857 	strcat(gSaveLine, yytext);
858 //	GenDebugLine();
859 //	GenListString();
860 	yylineno++;
861 	gLinesAssembled++;
862 }
863 
864 "#define"[ \t]+   {
865 	gbProcessingDefine = true;
866 	gMacroStartLine = yylineno;
867 	gCountParen = 0;
868 	BEGIN(MACRONAME);
869 }
870 
871 <SKIPLINE>.*\n	{
872 	BEGIN(SAVELINE);
873 //	GenDebugLine();
874 //	GenListString();
875 	gLinesAssembled++;
876 	yylineno++;
877 }
878 
879 "vs."{digits}"."{digits}[ \t]*[\n]? {
880 //	unsigned int majorVersion;
881 //	unsigned int minorVersion;
882 //	int minorOffset;
883 //
884 //
885 //	majorVersion = (unsigned int)(atoi(&yytext[3]));
886 //	// skip "ps." + second '.'
887 //	minorOffset = strcspn(&yytext[3], ".")+4;
888 //	minorVersion = (unsigned int)(atoi(&yytext[minorOffset]));
889 //	yylval.ival = D3DVS_VERSION(majorVersion, minorVersion);
890 //
891 
892 //	fprintf( stderr, "%s", yytext );
893 	if ( yytext[yyleng-1] == '\n' )
894 		line_incr = 1;
895 	return VERTEX_SHADER;
896 }
897 
898 {digits}	{
899 //	fprintf( stderr, "%s", yytext );
900 	vs10_lval.ival = atoi(yytext);
901 	return INTVAL;
902 }
903 
904 
905 {pt} {
906 		BEGIN(MODIFIER);
907 //fprintf( stderr, "." );
908 		return yytext[0];
909 }
910 
911 <MODIFIER>[w-z][w-z][w-z][w-z][ \t]*[\n]? {
912 //	fprintf( stderr, "%s", yytext );
913 	BEGIN(INITIAL);
914 
915 	vs10_lval.mask[0] = tolower(yytext[0]);
916 	vs10_lval.mask[1] = tolower(yytext[1]);
917 	vs10_lval.mask[2] = tolower(yytext[2]);
918 	vs10_lval.mask[3] = tolower(yytext[3]);
919 
920 	if ( yytext[yyleng-1] == '\n' )
921 		line_incr = 1;
922 
923 	return XYZW_MODIFIER;
924 
925 #if 0
926  	char temp[6];
927 
928 	temp[0] = '\0';
929 	strncat(temp, yytext, 4);
930 	strlwr(temp);
931 	vs10_lval.lval = FindSwizzleValue(temp);
932 
933 	BEGIN(INITIAL);
934 	return SWIZZLE_MODIFIER;
935 #endif
936 
937 }
938 
939 <MODIFIER>[w-z][w-z]?[w-z]?[w-z]?[ \t]*[\n]? {
940 //	fprintf( stderr, "%s", yytext );
941 	BEGIN(INITIAL);
942 
943 	int validLen = strspn(yytext, "xyzw");
944         int i;
945 	for ( i = 0; i < validLen; i++ )
946 		vs10_lval.mask[i] = tolower( yytext[i] );
947 	while ( i < 4 )
948 	{
949 		vs10_lval.mask[i] = 0;
950 		i++;
951 	}
952 
953 	if ( yytext[yyleng-1] == '\n' )
954 		line_incr = 1;
955 
956 	return XYZW_MODIFIER;
957 
958 #if 0
959  	//char temp[6];
960  	char *temp = new char[6];
961 	unsigned int registerMask;
962 	unsigned int validLen;
963 
964 	temp[0] = '\0';
965 	validLen = strspn(yytext, "xyzw");
966 	strncat(temp, yytext,  validLen);
967 	for ( int i = 0; i < validLen; i++ )
968 		temp[i] = tolower( temp[i] );
969 	registerMask = MakeRegisterMask(temp);
970 
971 	if (registerMask != 0)
972 	{
973 		//vs10_lval.sval = temp;
974 		vs10_lval.lval = registerMask;
975 		BEGIN(INITIAL);
976 		return XYZW_MODIFIER;
977 	}
978 	else
979 	{
980 		//vs10_lval.sval = temp;
981 		vs10_lval.lval = FindSwizzleValue(temp);
982 		BEGIN(INITIAL);
983 		return SWIZZLE_MODIFIER;
984 	}
985 #endif
986 }
987 
988 <MODIFIER>. {
989 		BEGIN(INITIAL);
990 		yyless(0);
991 }
992 
993 <MACRONAME>[^ \t(]+ {
994 	/* setup and save off #define/macro name */
995 	if (FindMacro(yytext) != NULL)
996 	{
997 		LexWarning("Redefinition of #define/macro %s, ignoring.\n", yytext);
998 		if (gbProcessingDefine)
999 		{
1000 			BEGIN(EATDEFINE);
1001 		}
1002 		else
1003 		{
1004 			BEGIN(EATMACRO);
1005 		}
1006 	}
1007 	else
1008 	{
1009 
1010 		BEGIN(MACROPARMSTART);
1011 		// %%%%% This should be setup to use memory pools
1012 		gTempMacro = (MACROENTRY *)malloc(sizeof(MACROENTRY));
1013 		if (gTempMacro == NULL)
1014 		{
1015 			LexError("Out of memory for macro table.\n");
1016 			if (gbProcessingDefine)
1017 			{
1018 				BEGIN(EATDEFINE);
1019 			}
1020 			else
1021 			{
1022 				BEGIN(EATMACRO);
1023 			}
1024 		}
1025 		else
1026 		{
1027 			gTempMacro->prev = gLastMacro;
1028 			gTempMacro->next = NULL;
1029 
1030 			gTempMacro->firstMacroParms = NULL;
1031 			gTempMacro->lastMacroParms = NULL;
1032 			gTempMacro->firstMacroLines = NULL;
1033 			gTempMacro->lastMacroLines = NULL;
1034 			gTempMacro->numParms = 0;
1035 			gTempMacro->bIsDefine = gbProcessingDefine;
1036 			gTempMacro->nLines = 0;
1037 
1038 			if (gCurFileName != NULL)
1039 			{
1040 				gTempMacro->fileName = strdup(gCurFileName);
1041 			}
1042 			else
1043 			{
1044 				gTempMacro->fileName = NULL;
1045 			}
1046 
1047 			gTempMacro->lineNo = yylineno;
1048 
1049 			/* %%%%% this should be set up in memory pools. */
1050 			gTempMacro->macroName = (char *)malloc(strlen(yytext)+1);
1051 			if (gTempMacro->macroName == NULL)
1052 			{
1053 				LexError("Out of memory for string table.\n");
1054 				SAFEFREE(gTempMacro);
1055 				if (gbProcessingDefine)
1056 				{
1057 					BEGIN(EATDEFINE);
1058 				}
1059 				else
1060 				{
1061 					BEGIN(EATMACRO);
1062 				}
1063 			}
1064 			else
1065 			{
1066 				strcpy(gTempMacro->macroName, yytext);
1067 			}
1068 		}
1069 	}
1070 }
1071 
1072 <MACRONAME>\n {
1073 	LexError("No macro name specified, skipping macro definition.\n");
1074 	SAFEFREE(gTempMacro->fileName);
1075 	SAFEFREE(gTempMacro);
1076 	if (gbProcessingDefine)
1077 	{
1078 		BEGIN(EATDEFINE);
1079 	}
1080 	else
1081 	{
1082 		BEGIN(EATMACRO);
1083 	}
1084 
1085 //	GenDebugLine();
1086 //	GenListString();
1087 	gLinesAssembled++;
1088 	yylineno++;
1089 }
1090 
1091 <MACROPARMSTART>"(" {
1092 	gCountParen++;
1093 }
1094 
1095 <MACROPARMSTART>[ \t]+ {}
1096 
1097 <MACROPARMSTART>. {
1098 	if (gbProcessingDefine && (gCountParen == 0))
1099 	{
1100 		EndMacroParms();
1101 	}
1102 	else
1103 	{
1104 		BEGIN(MACROPARM);
1105 	}
1106 	yyless(0);
1107 }
1108 
1109 <MACROPARM>[ \t]* {
1110 	if ((gCountParen == 0) && gbProcessingDefine)
1111 	{
1112 		EndMacroParms();
1113 	}
1114 }
1115 
1116 <MACROPARM>(";"|"//").* {
1117 	if (gCountParen == 0)
1118 	{
1119 		EndMacroParms();
1120 	}
1121 }
1122 
1123 <MACROPARM>"," {}
1124 
1125 <MACROPARM><<EOF>> {
1126 	EndMacroParms();
1127 //	GenDebugLine();
1128 //	GenListString();
1129 	yylineno++;
1130 	gLinesAssembled++;
1131 	BEGIN(INITIAL);
1132 }
1133 
1134 <MACROPARM>\n {
1135 	if (gbProcessingDefine && (gCountParen > 0))
1136 	{
1137 		LexError("Malformed #define, skipping.\n");
1138 		BEGIN(SAVELINE);
1139 	}
1140 	else
1141 	{
1142 		EndMacroParms();
1143 //		GenDebugLine();
1144 //		GenListString();
1145 		yylineno++;
1146 		gLinesAssembled++;
1147 		if (gbProcessingDefine)
1148 		{
1149 			gbProcessingDefine = false;
1150 			BEGIN(SAVELINE);
1151 		}
1152 	}
1153 }
1154 
1155 
1156 <MACROPARM>[^\n,]+ {
1157 
1158 	MACROTEXT *tMacro;
1159 	char *macroParmEnd;
1160 	unsigned int startOffset;
1161 	unsigned int leftParenCount;
1162 	unsigned int rightParenCount;
1163 
1164 	// sheesh, we gotta count the parenthesis....
1165 	macroParmEnd = yytext;
1166 	leftParenCount = 0;
1167 	rightParenCount = 0;
1168 	while (*macroParmEnd)
1169 	{
1170 		if (*macroParmEnd == ')')
1171 		{
1172 			rightParenCount++;
1173 		}
1174 		if (*macroParmEnd == '(')
1175 		{
1176 			leftParenCount++;
1177 		}
1178 
1179 		macroParmEnd++;
1180 	}
1181 
1182 	// if we found the last right parenthesis.
1183 	if (rightParenCount == leftParenCount+1)
1184 	{
1185 		// find if we got the last parenthesis on this line
1186 		macroParmEnd = strrchr(yytext, ')');
1187 		yyless((macroParmEnd - yytext));
1188 		BEGIN(MACROPARMEND);
1189 	}
1190 
1191 	startOffset = strspn(yytext, " \t");
1192 
1193 	tMacro = SaveMacroText(&yytext[startOffset], gTempMacro->lastMacroParms);
1194 	if (tMacro == NULL)
1195 	{
1196 		LexError("Out of memory for string table for macro parameter(s).\n");
1197 		FreeMacroEntry(gTempMacro);
1198 		BEGIN(EATMACRO);
1199 	}
1200 	else
1201 	{
1202 		// if first one wasn't set then set it
1203 		if (gTempMacro->firstMacroParms == NULL)
1204 		{
1205 			gTempMacro->firstMacroParms = tMacro;
1206 		}
1207 
1208 		gTempMacro->lastMacroParms = tMacro;
1209 
1210 		gTempMacro->numParms++;
1211 	}
1212 
1213 }
1214 
1215 <MACROPARMEND>")"[ \t]*"\\"*\n* {
1216 	if (!gbProcessingDefine && !gbTempInsideMacro)
1217 	{
1218 		LexError("Malformed  macro, skipping.\n");
1219 		BEGIN(EATMACRO);
1220 	}
1221 	else
1222 	{
1223 		gCountParen--;
1224 
1225 		// we can get multiple \n's here
1226 		while (yytext[yyleng-2] == '\n')
1227 		{
1228 			yyleng--;
1229 		}
1230 		yyless(yyleng);
1231 
1232 		// if there isn't a \n on this line, macro starts on this line,
1233 		// not next, like in a macro definition
1234 		if (yytext[yyleng-1] != '\n')
1235 		{
1236 			EndMacroParms();
1237 		}
1238 		else
1239 		{
1240 			if (yytext[yyleng-1] == '\n')
1241 			{
1242 				gTempMacro->lineNo++;
1243 			}
1244 			// count this line
1245 			gTempMacro->nLines++;
1246 //			GenDebugLine();
1247 //			GenListString();
1248 			EndMacroParms();
1249 			if (!gbInsideMacro)
1250 			{
1251 				yylineno++;
1252 			}
1253 
1254 			gLinesAssembled++;
1255 		}
1256 
1257 	}
1258 }
1259 
1260 <MACROPARMEND>")"[ \t]*(";"|"//").*\n {
1261 	if (!gbProcessingDefine && !gbTempInsideMacro)
1262 	{
1263 		LexError("Malformed  macro, skipping.\n");
1264 		BEGIN(EATMACRO);
1265 	}
1266 	else
1267 	{
1268 
1269 		// no matter what count this line
1270 		gTempMacro->nLines++;
1271 		gCountParen--;
1272 		EndMacroParms();
1273 		if (!gbInsideMacro)
1274 		{
1275 			yylineno++;
1276 		}
1277 
1278 		gLinesAssembled++;
1279 	}
1280 }
1281 
1282 <MACROPARMEND>")"[ \t]+ {
1283 	if (!gbProcessingDefine && !gbTempInsideMacro)
1284 	{
1285 		LexError("Malformed  macro, skipping.\n");
1286 		BEGIN(EATMACRO);
1287 	}
1288 	else
1289 	{
1290 		gCountParen--;
1291 		if (gCountParen == 0)
1292 		{
1293 			// no matter what count this line
1294 			gTempMacro->nLines++;
1295 			EndMacroParms();
1296 			if (!gbInsideMacro)
1297 			{
1298 				yylineno++;
1299 			}
1300 
1301 			gLinesAssembled++;
1302 		}
1303 		else
1304 		{
1305 			REJECT;
1306 		}
1307 	}
1308 }
1309 
1310 <MACROBODY>.*"\\"[ \t]*\n {
1311 	MACROTEXT *tMacro;
1312 	unsigned int copyLen;
1313 	char *endLine;
1314 
1315 	gSaveLine[0] ='\0';
1316 	endLine = strchr(yytext, '\\');
1317 	copyLen = (endLine - yytext);
1318 	if (copyLen > MAXSAVELINE)
1319 	{
1320 		copyLen = MAXSAVELINE;
1321 	}
1322 
1323 	strncat(gSaveLine, yytext, copyLen);
1324 	strcat(gSaveLine, "\n");
1325 	tMacro = SaveMacroText(gSaveLine, gLastMacro->lastMacroLines);
1326 	if (tMacro == NULL)
1327 	{
1328 		LexError("Out of memory for string table for macro parameter(s).\n");
1329 		BEGIN(EATDEFINE);
1330 	}
1331 	else
1332 	{
1333 		gLastMacro->nLines++;
1334 		// if first one wasn't set then set it
1335 		if (gLastMacro->firstMacroLines == NULL)
1336 		{
1337 			gLastMacro->firstMacroLines = tMacro;
1338 		}
1339 
1340 		gLastMacro->lastMacroLines = tMacro;
1341 	}
1342 
1343 //	GenDebugLine();
1344 //	GenListString();
1345 	yylineno++;
1346 	gLinesAssembled++;
1347 }
1348 
1349 <MACROBODY>[ \t]*"endm"[ \t]*((";"|"//").*)* {
1350 
1351 	strncpy(gSaveLine, yytext, MAXSAVELINE);
1352 	if (gbProcessingDefine)
1353 	{
1354 		LexError("Malformed #define, skipping.\n");
1355 	}
1356 
1357 	BEGIN(ENDMACRO);
1358 }
1359 
1360 <MACROBODY>[^\n]* {
1361 		MACROTEXT *tMacro;
1362 
1363 		// check if processing #define and only one line, if not then append \n
1364 		if (!gbProcessingDefine || (gLastMacro->nLines >= 1))
1365 		{
1366 			gSaveLine[0] = '\0';
1367 			strncat(gSaveLine, yytext, MAXSAVELINE);
1368 			strcat(gSaveLine, "\n");
1369 			tMacro = SaveMacroText(gSaveLine, gLastMacro->lastMacroLines);
1370 			gLastMacro->nLines++;
1371 		}
1372 		else if (gLastMacro->numParms > 0)	// check if parameters were there
1373 		{
1374 			// if so, we need the '\n' appended
1375 			gMacroLine[0] = '\0';
1376 			strncat(gMacroLine, yytext, MAXSAVELINE);
1377 			strcat(gMacroLine, "\n");
1378 			tMacro = SaveMacroText(gMacroLine, gLastMacro->lastMacroLines);
1379 			gLastMacro->nLines++;
1380 		}
1381 		else	// straight no newline macro replace
1382 		{
1383 			tMacro = SaveMacroText(yytext, gLastMacro->lastMacroLines);
1384 		}
1385 
1386 		if (tMacro == NULL)
1387 		{
1388 			LexError("Out of memory for string table for macro parameter(s).\n");
1389 			BEGIN(EATMACRO);
1390 		}
1391 		else
1392 		{
1393 			// if first one wasn't set then set it
1394 			if (gLastMacro->firstMacroLines == NULL)
1395 			{
1396 				gLastMacro->firstMacroLines = tMacro;
1397 			}
1398 
1399 			gLastMacro->lastMacroLines = tMacro;
1400 		}
1401 }
1402 
1403 <MACROBODY>\n {
1404 
1405 	MACROTEXT *tMacro;
1406 //	GenDebugLine();
1407 //	GenListString();
1408 	yylineno++;
1409 	gLinesAssembled++;
1410 	if (gbProcessingDefine)
1411 	{
1412 		gbProcessingDefine = false;
1413 		BEGIN(SAVELINE);
1414 	}
1415 	else
1416 	{
1417 		// this means \n by itself inside macro body
1418 		if (((yylineno-1) - gLastMacro->lineNo) !=  gLastMacro->nLines)
1419 		{
1420 			strcpy(gMacroLine, "\n");
1421 			tMacro = SaveMacroText(gMacroLine, gLastMacro->lastMacroLines);
1422 			gLastMacro->nLines++;
1423 
1424 			if (tMacro == NULL)
1425 			{
1426 				LexError("Out of memory for string table for macro parameter(s).\n");
1427 				BEGIN(EATMACRO);
1428 			}
1429 			else
1430 			{
1431 				// if first one wasn't set then set it
1432 				if (gLastMacro->firstMacroLines == NULL)
1433 				{
1434 					gLastMacro->firstMacroLines = tMacro;
1435 				}
1436 
1437 				gLastMacro->lastMacroLines = tMacro;
1438 			}
1439 		}
1440 	}
1441 }
1442 
1443 <EATMACRO>[ \t]*"endm"[ \t]*\n {
1444 	BEGIN(SAVELINE);
1445 //	GenDebugLine();
1446 //	GenListString();
1447 	gLinesAssembled++;
1448 	yylineno++;
1449 }
1450 
1451 <EATMACRO>.*\n {
1452 	strncpy(gSaveLine, yytext, MAXSAVELINE);
1453 //	GenDebugLine();
1454 //	GenListString();
1455 	gLinesAssembled++;
1456 	yylineno++;
1457 }
1458 
1459 <EATDEFINE>.*"\\"\n {
1460 	strncpy(gSaveLine, yytext, MAXSAVELINE);
1461 //	GenDebugLine();
1462 //	GenListString();
1463 	gLinesAssembled++;
1464 	yylineno++;
1465 }
1466 
1467 <EATDEFINE>.*\n {
1468 	strncpy(gSaveLine, yytext, MAXSAVELINE);
1469 //	GenDebugLine();
1470 //	GenListString();
1471 	gLinesAssembled++;
1472 	yylineno++;
1473 	BEGIN(SAVELINE);
1474 }
1475 
1476 <INITIAL,MODIFIER>{alpha}{alphadigs}* {
1477 
1478 	gTempParseMacro = FindMacro(yytext);
1479 
1480 	if (gTempParseMacro != NULL)
1481 	{
1482 		if (gIncludeStackIndex >= MAX_INCLUDE_DEPTH )
1483 		{
1484 			LexError("macros nested too deeply");
1485 			exit( 1 );
1486 		}
1487 
1488 		if (gTempParseMacro->firstMacroLines != NULL)
1489 		{
1490 
1491 			gTempMacro = (MACROENTRY *)malloc(sizeof(MACROENTRY));
1492 			if (gTempMacro == NULL)
1493 			{
1494 				LexError("Out of memory allocating MACROENTRY structure.\n");
1495 			}
1496 			else
1497 			{
1498 
1499 				gTempMacro->next = NULL;
1500 				gTempMacro->prev = NULL;
1501 				gTempMacro->macroName = NULL;
1502 				gTempMacro->firstMacroParms = NULL;
1503 				gTempMacro->lastMacroParms = NULL;
1504 				gTempMacro->firstMacroLines = NULL;
1505 				gTempMacro->lastMacroLines = NULL;
1506 				gTempMacro->numParms = 0;
1507 				gTempMacro->nLines = 0;
1508 
1509 				gbTempInsideMacro = true;		// flag we are currently doing a macro replace.
1510 				gInvokeState = YYSTATE;
1511 				if (gTempParseMacro->numParms > 0)
1512 				{
1513 					BEGIN(MACROPARMSTART);
1514 				}
1515 				else
1516 				{
1517 					EndMacroParms();
1518 					gbTempInsideMacro = false;	// no longer waiting for macro invocation
1519 				}
1520 			}
1521 		}
1522 	}
1523 	else
1524 	{
1525 		BEGIN(INITIAL);
1526 		REJECT;
1527 	}
1528 }
1529 
1530 [,\[\]\-\+\(\)\*\<\>\/\%_\.] {
1531 //    fprintf( stderr, "%c ", yytext[0] );
1532 	return yytext[0];
1533 }
1534 
1535 
1536 [ \t]+	{}
1537 
1538 <DEFINE>\n {
1539 	LexError("Didn't find label string for #define.\n");
1540 	BEGIN(SAVELINE);
1541 //	return '\n';
1542 }
1543 
1544 "\n" {
1545 //fprintf(stderr, "\n");
1546 //	line_incr = 1;
1547 	line_incr++;
1548 	BEGIN(SAVELINE);
1549 	return '\n';
1550 }
1551 
1552 <EATSTRING>{alphadigs}+ {
1553 	BEGIN(INITIAL);
1554 //	fprintf( stderr, "%s", yytext );
1555 	if (yyleng == 1)
1556 		return yytext[0];
1557 	else
1558 		LexError("Unrecognized Token: %s\n", yytext);
1559 	return UNKNOWN_STRING;
1560 }
1561 
1562 <EATSTRING>[\001-\040]		{
1563 //	vs10_lval.ival = yytext[0];
1564 	LexError("Illegal character: %d decimal.\n", yytext[0]);
1565 	return(ILLEGAL);
1566 }
1567 
1568 [\001-\040]		{
1569 //	vs10_lval.ival = yytext[0];
1570 	LexError("Illegal character: %d decimal.\n", yytext[0]);
1571 	return(ILLEGAL);
1572 }
1573 
1574 <EATSTRING>. {
1575 	return yytext[0];
1576 }
1577 
1578 . {
1579 	BEGIN(EATSTRING);
1580 	yyless(0);
1581 }
1582 
1583 <<EOF>> {
1584 	bool wasInMacro;
1585 	bool oneLiner;
1586 	char *macroText;
1587 
1588 	wasInMacro = gbInsideMacro;
1589 	oneLiner = false;
1590 
1591 
1592 	// if we are inside the macro then do next line until their are no more
1593 	if (gbInsideMacro)
1594 	{
1595 		oneLiner = (gParseMacro->nLines == 0);
1596 
1597 		// free the temporary parameter replaced line we were working on.
1598 		// get next line in macro text, if any
1599 		gMacroLineParse = gMacroLineParse->next;
1600 		// more lines to parse?
1601 		if (gMacroLineParse != NULL)
1602 		{
1603 			macroText = gMacroLine;
1604 			// if no replacement text, just use source line
1605 			if (gParseMacro->firstMacroParms == NULL)
1606 			{
1607 				macroText = gMacroLineParse->macroText;
1608 			}
1609 			else
1610 			{
1611 				// replace the macro parameters
1612 				ReplaceMacroParms(gMacroLineParse->macroText, gMacroLine, gParseMacro, gInvokeMacro);
1613 			}
1614 
1615 //			if (gExpandMacros)
1616 //			{
1617 //				strcpy(gSaveLine, macroText);
1618 //			}
1619 
1620 			BEGIN(INITIAL);
1621 			// and lex it.
1622 			yy_scan_string(macroText);
1623 		}
1624 		else
1625 		{
1626 			// no more lines in this macro, so free the working macro
1627 			SAFEFREE(gInvokeMacro);
1628 			// shut off flag for inside a macro replacement state.
1629 			gbInsideMacro = false;
1630 		}
1631 	}
1632 
1633 	if (gbProcessingIFDEF && !wasInMacro)
1634 	{
1635 		LexError("End of file reached before #endif found, macro started on line %d.\n", gIfDefStartLine);
1636 	}
1637 
1638 	if (!gbInsideMacro)
1639 	{
1640 		if ( gIncludeStackIndex == 0 )
1641 		{
1642 			if (!gbProcessingBuiltIn)
1643 				CleanUp();
1644 			return 0;
1645 //			return TOKEN_EOF;
1646 		}
1647 		else
1648 		{
1649 			yy_delete_buffer( YY_CURRENT_BUFFER );
1650 			SAFEFREE(gCurFileName);
1651 //			SAFEDELETE(myin);
1652 //			SAFECLOSE(yyin);
1653 		}
1654 
1655 		gIncludeStackIndex--;
1656 		SAFEDELETEARRAY( gIncludeStack[gIncludeStackIndex].nextString );
1657 		yy_switch_to_buffer(gIncludeStack[gIncludeStackIndex].buffer );
1658 		gCurFileName = gIncludeStack[gIncludeStackIndex].fileName;
1659 //		yyin = gIncludeStack[gIncludeStackIndex].fileHandle;
1660 		myin = gIncludeStack[gIncludeStackIndex].prevString;
1661 		yylineno = gIncludeStack[gIncludeStackIndex].lineNo;
1662 		gInvokeMacro = gIncludeStack[gIncludeStackIndex].lastInvokeMacro;
1663 		gParseMacro = gIncludeStack[gIncludeStackIndex].lastParseMacro;
1664 		gMacroLineParse = gIncludeStack[gIncludeStackIndex].lastMacroLineParse;
1665 		gbInsideInclude = gIncludeStack[gIncludeStackIndex].lastbInsideInclude;
1666 		gbInsideMacro = gIncludeStack[gIncludeStackIndex].lastbInsideMacro;
1667 		gbProcessingIFDEF = gIncludeStack[gIncludeStackIndex].lastbProcessingIFDEF;
1668 
1669 		if (!gbInsideMacro && !oneLiner)
1670 		{
1671 //			GenSwitchFileNames(gCurFileName);
1672 			BEGIN(SAVELINE);
1673 		}
1674 		else
1675 		{
1676 			BEGIN(INITIAL);
1677 		}
1678 
1679 		// gSaveLine was last line saved, before macro invocation
1680 		if (wasInMacro && !gbInsideMacro && !oneLiner)
1681 		{
1682 //			GenDebugLine();
1683 //			GenListString();
1684 			gLinesAssembled++;
1685 			yylineno++;
1686 		}
1687 
1688 	}
1689 
1690 }
1691 
1692 %%
1693 
1694 
1695 //=====================================================================
1696 // Function:	FindNMacro
1697 // Description:	Look through macros and see if it had been predefined
1698 // Parameters:	findName = name to lookup
1699 //				sLen = # characters valid in source (findName)
1700 // Returns:		MACROENTRY * = pointer to macro entry if found
1701 //=====================================================================
1702 MACROENTRY *FindNMacro(char *findName, unsigned int sLen)
1703 {
1704 	MACROENTRY *curEntry;
1705 
1706 	curEntry = gLastMacro;
1707 	while (curEntry != NULL)
1708 	{
1709 		if (strlen(curEntry->macroName) == sLen)
1710 		{
1711 			if (!strncmp(curEntry->macroName, findName, sLen))
1712 			{
1713 				break;
1714 			}
1715 		}
1716 
1717 		curEntry = curEntry->prev;
1718 	}
1719 
1720 	return curEntry;
1721 
1722 }
1723 
1724 //=====================================================================
1725 // Function:	FindMacro
1726 // Description:	Look through macros and see if it had been predefined
1727 // Parameters:	findName = name to lookup
1728 // Returns:		MACROENTRY * = pointer to macro entry if found
1729 //=====================================================================
1730 MACROENTRY *FindMacro(char *findName)
1731 {
1732 	MACROENTRY *curEntry;
1733 
1734 	curEntry = gLastMacro;
1735 	while (curEntry != NULL)
1736 	{
1737 		if (!strcmp(curEntry->macroName, findName))
1738 		{
1739 			break;
1740 		}
1741 
1742 		curEntry = curEntry->prev;
1743 	}
1744 
1745 	return curEntry;
1746 
1747 }
1748 
1749 //=====================================================================
1750 // Function:	CleanUp
1751 // Description:	Clean up the #define strings
1752 // Parameters:	.
1753 // Returns:		.
1754 //=====================================================================
1755 void CleanUp()
1756 {
1757 	void *tPtr;
1758 
1759 	// free up the macros that were alloced
1760 	while (gLastMacro != NULL)
1761 	{
1762 
1763 		FreeMacroEntry(gLastMacro);
1764 
1765 		tPtr = gLastMacro;
1766 		gLastMacro = gLastMacro->prev;
1767 		SAFEFREE(tPtr);
1768 	}
1769 
1770 }
1771 
1772 //=====================================================================
1773 // Function:	FreeMacroEntry
1774 // Description:	Frees up the macro entry data, (parms, lines of text)
1775 // Parameters:	macEntry = pointer to the MACROENTRY structure
1776 // Returns:		.
1777 //=====================================================================
1778 void FreeMacroEntry(MACROENTRY *macEntry)
1779 {
1780 	MACROTEXT *tText;
1781 	MACROTEXT *tNext;
1782 
1783 	SAFEFREE(macEntry->macroName);
1784 	SAFEFREE(macEntry->fileName);
1785 	// free the macro lines that were alloced
1786 	tText = macEntry->lastMacroLines;
1787 	while (tText != NULL)
1788 	{
1789 		tNext = tText->prev;
1790 		SAFEFREE(tText);
1791 		tText = tNext;
1792 	}
1793 
1794 	// free the text of the macro parms that were alloced
1795 	tText = macEntry->lastMacroParms;
1796 	while (tText != NULL)
1797 	{
1798 		tNext = tText->prev;
1799 		SAFEFREE(tText);
1800 		tText = tNext;
1801 	}
1802 }
1803 
1804 //=====================================================================
1805 // Function:	CheckMacroFunctions
1806 // Description:	Find if this text is a builtin macro function
1807 // Parameters:	lookString = non-null terminated string of possible
1808 //				and if found set global macro function call
1809 // Returns:		.
1810 //=====================================================================
1811 void CheckMacroFunctions(char *lookString, unsigned int *recognizedLen, char **invString)
1812 {
1813 
1814 	unsigned int i;
1815 	unsigned int sLen;
1816 
1817 	for (i=0; i< NUM_MACRO_FUNCTIONS; i++)
1818 	{
1819 		sLen = strlen(gMacroFunctions[i].name);
1820 		if (!strncmp(gMacroFunctions[i].name, lookString, sLen))
1821 		{
1822 			gMacroCallFunction = gMacroFunctions[i].function;
1823 			*recognizedLen = sLen;
1824 			*invString = NULL;
1825 			return;
1826 		}
1827 	}
1828 }
1829 
1830 //=====================================================================
1831 // Function:	FindAlphaNum
1832 // Description:	Find a whole alpha numeric string, ie consists of
1833 //				[A-Za-z0-9_] only
1834 // Parameters:	srcStr = source string to search through.
1835 //				sLen = unsinged int pointer to length of string found
1836 // Returns:		pointer to found start of string.
1837 //				NULL if none.
1838 //=====================================================================
1839 char *FindAlphaNum(char *srcStr, unsigned int *sLen)
1840 {
1841 	char curChar;
1842 	char *foundStr;
1843 
1844 	while (*srcStr != '\0')
1845 	{
1846 		curChar = toupper(*srcStr);
1847 		if ((curChar >= 'A') && (curChar <= 'Z'))
1848 			break;
1849 
1850 		if ((curChar >= '0') && (curChar <='9'))
1851 			break;
1852 
1853 		if (curChar == '_')
1854 			break;
1855 
1856 		srcStr++;
1857 	}
1858 
1859 	if (*srcStr == '\0')
1860 	{
1861 		return NULL;
1862 	}
1863 
1864 	foundStr = srcStr;
1865 
1866 	*sLen = 0;
1867 	// now search for end of string of [A-Za-z0-9_]
1868 	while (*srcStr != '\0')
1869 	{
1870 		curChar = toupper(*srcStr);
1871 		if ((curChar < 'A') || (curChar > 'Z'))
1872 		{
1873 			if ((curChar < '0') || (curChar > '9'))
1874 			{
1875 				if (curChar != '_')
1876 					break;
1877 			}
1878 		}
1879 
1880 		(*sLen)++;
1881 		srcStr++;
1882 	}
1883 
1884 	return foundStr;
1885 
1886 }
1887 
1888 //=====================================================================
1889 // Function:	FindDefineParm
1890 // Description:	Find if the MACROENTRY->macroText linked list contains
1891 //				replaceable parameters.
1892 // Parameters:	srcParms = pointer to MACROENTRY structure for source
1893 //						parameters
1894 //				invParms = MACROENTRY pointer to invocation parameters
1895 //				lookString = non-null terminated string of possible
1896 //							replaceable string
1897 //				recognizedLen = replacement string matched length
1898 //				invString = invocation string to replace with
1899 // Returns:		pointer to first character found in lookstring
1900 //=====================================================================
1901 char *FindDefineParm(MACROENTRY *srcParms, MACROENTRY *invParms,
1902 						char *lookString, unsigned int *recognizedLen, char **invString)
1903 {
1904 	MACROTEXT *srcText;
1905 	MACROTEXT *invText;
1906 	char *checkStr;
1907 	unsigned int checkLen = 0;
1908 	unsigned int sLen;
1909 
1910 	checkStr = lookString;
1911 	*invString = NULL;
1912 
1913 	// first search for first [A-Za-z0-9_] only string
1914 	checkStr = FindAlphaNum(lookString, &checkLen);
1915 
1916 	while (checkStr != NULL)
1917 	{
1918 		// check all the #define parameters for match
1919 		srcText = srcParms->firstMacroParms;
1920 		invText = invParms->firstMacroParms;
1921 		while (srcText)
1922 		{
1923 			sLen = strlen(srcText->macroText);
1924 			// lengths should match
1925 			if (sLen == checkLen)
1926 			{
1927 				if (!strncmp(checkStr, srcText->macroText, checkLen))
1928 				{
1929 					// it matched so return replacement text
1930 					*invString = invText->macroText;
1931 					// and length that we recognized
1932 					*recognizedLen = checkLen;
1933 					return checkStr;
1934 				}
1935 			}
1936 
1937 			srcText = srcText->next;
1938 			invText = invText->next;
1939 		}
1940 
1941 		// not found yet, so go to next string.
1942 		checkStr = FindAlphaNum(checkStr+checkLen, &checkLen);
1943 	}
1944 
1945 	return NULL;
1946 }
1947 
1948 //=====================================================================
1949 // Function:	FindReplaceParm
1950 // Description:	Find if the MACROENTRY->macroText linked list contains
1951 //				a replaceable parameters.
1952 // Parameters:	srcParms = pointer to MACROENTRY structure for source
1953 //						parameters
1954 //				invParms = MACROENTRY pointer to invocation parameters
1955 //				lookString = non-null terminated string of possible
1956 //							replaceable string
1957 //				recognizedLen = replacement string matched length
1958 //				invString = invocation string to replace with
1959 // Returns:		.
1960 //=====================================================================
1961 void FindReplaceParm(MACROENTRY *srcParms, MACROENTRY *invParms,
1962 						char *lookString, unsigned int *recognizedLen, char **invString)
1963 {
1964 	unsigned int sLen;
1965 	MACROTEXT *srcText;
1966 	MACROTEXT *invText;
1967 
1968 	*recognizedLen = 0;
1969 	*invString = NULL;
1970 
1971 	srcText = srcParms->firstMacroParms;
1972 	invText = invParms->firstMacroParms;
1973 
1974 	if (srcText != NULL)
1975 	{
1976 		// go until srcText # strings ends
1977 		while (srcText != NULL)
1978 		{
1979 			sLen = strlen(srcText->macroText);
1980 			if (!strncmp(srcText->macroText, lookString, sLen))
1981 			{
1982 				// found it so return src, replacement string
1983 				*recognizedLen = strlen(srcText->macroText);
1984 				*invString = invText->macroText;
1985 				// call function macro if it was invoked prior.
1986 				if (gMacroCallFunction != NULL)
1987 				{
1988 					gMacroCallFunction(lookString, recognizedLen, invString);
1989 					gMacroCallFunction = NULL;
1990 				}
1991 				return;
1992 			}
1993 
1994 			srcText = srcText->next;
1995 			invText = invText->next;
1996 		}
1997 	}
1998 
1999 	// ok, it wasn't found, look through builtin macro functions
2000 	CheckMacroFunctions(lookString, recognizedLen, invString);
2001 }
2002 
2003 //=====================================================================
2004 // Function:	ReplaceMacroParms
2005 // Description:	Replace macro parameters when macro was defined, with
2006 //				those specified on the macro invocation line
2007 // Parameters:	srcLine = source line to replace src macro parms with
2008 //				destLine = destination line save to.
2009 //				invocation macro parameters.
2010 //				parseMacro = currently parsing macro entry
2011 //				invParms = invocation macro entry
2012 // Returns:		.
2013 //=====================================================================
2014 void ReplaceMacroParms(char *srcLine, char *destLine,
2015 							MACROENTRY *srcParms, MACROENTRY *invParms)
2016 {
2017 	char *findReplace;
2018 	char *invString;
2019 	unsigned int sLen;
2020 	unsigned int dLen;
2021 	unsigned int copyLen;
2022 	unsigned int subLen;
2023 	unsigned int recognizedLen;
2024 
2025 	destLine[0]= '\0';
2026 
2027 	sLen = strlen(srcLine);
2028 	dLen = 0;
2029 
2030 	while (sLen > 0)
2031 	{
2032 		// strtok might work better except it modifies the string, so
2033 		// kind of do my own....
2034 		if (!srcParms->bIsDefine)
2035 		{
2036 			findReplace = strchr(srcLine, '%');
2037 			if (findReplace != NULL)
2038 			{
2039 				// bypass % sign in findReplacement
2040 				findReplace++;
2041 				// figure out length of source before %
2042 				copyLen = (findReplace - srcLine)-1;
2043 				// check if there is a replacement string
2044 				FindReplaceParm(srcParms, invParms, findReplace, &recognizedLen, &invString);
2045 			}
2046 			else
2047 			{
2048 				strcat(destLine, srcLine);
2049 				return;
2050 			}
2051 		}
2052 		else
2053 		{
2054 			findReplace = FindDefineParm(srcParms, invParms, srcLine, &recognizedLen, &invString);
2055 			if (findReplace != NULL)
2056 			{
2057 				// figure out length of source before %
2058 				copyLen = findReplace - srcLine;
2059 			}
2060 			else
2061 			{
2062 				strcat(destLine, srcLine);
2063 				return;
2064 			}
2065 		}
2066 
2067 
2068 		if (invString != NULL)
2069 		{
2070 			// figure out how much we are going to substitute
2071 			subLen = strlen(invString);
2072 		}
2073 		else
2074 		{
2075 			subLen = 0;
2076 		}
2077 
2078 		if ((dLen + copyLen + subLen) > MAXSAVELINE)
2079 		{
2080 			LexError("Macro string overrun.\n");
2081 			CleanUp();
2082 			exit(ERROR_MACRO_OVERRUN);
2083 		}
2084 
2085 		if (copyLen > 0)
2086 		{
2087 			strncat(destLine, srcLine, copyLen);
2088 			dLen += copyLen;
2089 		}
2090 
2091 		srcLine += copyLen;
2092 		sLen -= copyLen;
2093 		// in macro so skip % part of variable
2094 		if (!srcParms->bIsDefine)
2095 		{
2096 			// skip %, also
2097 			srcLine++;
2098 			sLen--;
2099 		}
2100 
2101 		if (invString != NULL)
2102 		{
2103 			strcat(destLine, invString);
2104 			dLen += strlen(invString);
2105 		}
2106 
2107 		srcLine += recognizedLen;
2108 		sLen -= recognizedLen;
2109 	}
2110 
2111 }
2112 
2113 //=====================================================================
2114 // Function:	SaveMacroText
2115 // Description:	Adds a string to a linked list of MACROTEXT structures
2116 // Parameters:	srcText = pointer to source text to save
2117 //				lastMacroText = last allocated, or NULL
2118 // Returns:		newly allocated MACROTEXT structure, or NULL
2119 //=====================================================================
2120 MACROTEXT *SaveMacroText(char *srcText, MACROTEXT *lastMacroText)
2121 {
2122 	MACROTEXT *curMacroText;
2123 
2124 	curMacroText = (MACROTEXT *)malloc(sizeof(MACROTEXT));
2125 	if (curMacroText == NULL)
2126 	{
2127 		return NULL;
2128 	}
2129 	else
2130 	{
2131 		// no next entry but set up previous with previously alloced macro parameter
2132 		curMacroText->next = NULL;
2133 		curMacroText->prev = lastMacroText;
2134 
2135 		// if the macroParm pointer is null then we are the first allocated
2136 		// so if not set the last one allocate next pointer to newly allocated structure
2137 		if (lastMacroText != NULL)
2138 		{
2139 			lastMacroText->next = curMacroText;
2140 		}
2141 
2142 		/* %%%%% this should be set up in memory pools. */
2143 		curMacroText->macroText = strdup(srcText);
2144 		if (curMacroText->macroText == NULL)
2145 		{
2146 			SAFEFREE(curMacroText);
2147 			return NULL;
2148 		}
2149 	}
2150 
2151 	return curMacroText;
2152 }
2153 
2154 //=====================================================================
2155 // Function:	ParseBuiltInMacroParms
2156 // Description:	parse parameters of string and fill in MACROENTRY
2157 //				structure.
2158 // Parameters:	parsedMacro = pointer to MACROENTRY structure that gets
2159 //				filled in with parameter pointers and count
2160 //				parmStr = string to parse parameters from
2161 // Returns:		false if error
2162 //=====================================================================
2163 bool ParseBuiltInMacroParms(MACROENTRY *parsedMacro, char *parmStr)
2164 {
2165 	char *endStr;
2166 	char *foundParm;
2167 	MACROTEXT *prevMT;
2168 	MACROTEXT *curMT;
2169 
2170 	parsedMacro->numParms = 0;
2171 	parsedMacro->firstMacroParms = NULL;
2172 
2173 	foundParm = strdup(parmStr);
2174 	if (foundParm == NULL)
2175 	{
2176 		LexError("Out of memory parsing bultin macro parameters.\n");
2177 		return false;
2178 	}
2179 
2180 	// assume a ')' is on the end.
2181 	endStr = strrchr(foundParm, ')');
2182 	if (endStr == NULL)
2183 	{
2184 		LexWarning("Ending parenthesis not found for macro %s.\n", parsedMacro->macroName);
2185 		endStr = foundParm + strlen(foundParm);
2186 	}
2187 
2188 	prevMT = NULL;
2189 	// strip out and separate parameters
2190 	while (foundParm < endStr)
2191 	{
2192 		// allocate a macro text structure
2193 		curMT = (MACROTEXT *)malloc(sizeof(MACROTEXT));
2194 		if (curMT == NULL)
2195 		{
2196 			free(parmStr);
2197 			LexError("Out of memory parsing bultin macro parameters.\n");
2198 			return false;
2199 		}
2200 		curMT->next = NULL;
2201 		curMT->prev = prevMT;
2202 		parsedMacro->numParms++;
2203 
2204 		if (prevMT != NULL)
2205 		{
2206 			prevMT->next = curMT;
2207 		}
2208 		else
2209 		{
2210 			parsedMacro->firstMacroParms = curMT;
2211 		}
2212 
2213 		curMT->macroText = foundParm;
2214 		// search for next parameters, delimited by comma
2215 		foundParm = strchr(foundParm, ',');
2216 		if (foundParm == NULL)
2217 		{
2218 			foundParm = endStr;
2219 			*foundParm = '\0';
2220 		}
2221 		else
2222 		{
2223 			// skip comma
2224 			*foundParm = '\0';
2225 			foundParm++;
2226 		}
2227 		prevMT = curMT;
2228 	}
2229 
2230 	return true;
2231 }
2232 
2233 //=====================================================================
2234 // Function:	MacroMathFunction
2235 // Description:	Comes here after macro replacement is done to perform
2236 //				some mathematic function on parameter (macro replacement
2237 //				 string (ie, register))
2238 // Parameters:	invMacro = macroentry pointer containing macro information
2239 //				recognizedLen = # characters recoginized so far
2240 //				invStr = invoked replacement string so far
2241 //				mathStr = "-", "+", etc for mathematic function
2242 // Returns:		new recognizedLen, invStr, with incremented #
2243 //=====================================================================
2244 void MacroMathFunction(MACROENTRY *invMacro, unsigned int *recognizedLen, char **invStr,
2245 						const char *mathStr)
2246 {
2247 	char *numStartStr;
2248 	unsigned int sLen;
2249 	char numberStr[256];
2250 	unsigned int number = 0;
2251 	char *operand;
2252 
2253 
2254 	// verify enough paramters to complete operation
2255 	if (invMacro->numParms != 2)
2256 	{
2257 		LexError("Two parameters are required for %s macro\n", invMacro->macroName);
2258 		return;
2259 	}
2260 
2261 	// get second macro parm, which is add by amount.
2262 	operand = invMacro->firstMacroParms->next->macroText;
2263 
2264 	// first find inner most bracket if any
2265 	numStartStr = strrchr(*invStr, ']');
2266 	if (numStartStr == NULL)
2267 	{
2268 		numStartStr = strrchr(*invStr, ')');
2269 	}
2270 
2271 	if (numStartStr != NULL)
2272 	{
2273 		if ((strlen(*invStr)+strlen(operand)+1) > MAXREPLACESTRING)
2274 		{
2275 			LexError("Out of Temporary string replacement memory inside builtin macro %s\n",
2276 					invMacro->macroName);
2277 		}
2278 		else
2279 		{
2280 			sLen = (numStartStr - *invStr);
2281 			gReplaceText[0] = '\0';
2282 			strncat(gReplaceText, *invStr, sLen);
2283 			strcat(gReplaceText, mathStr);
2284 			strcat(gReplaceText, operand);
2285 			strcat(gReplaceText, numStartStr);
2286 			*invStr = gReplaceText;
2287 		}
2288 	}
2289 	else
2290 	{
2291 		numStartStr = strpbrk(*invStr, "0123456789");
2292 		if (numStartStr != NULL)
2293 		{
2294 			// put up to number we found
2295 			sLen = numStartStr - *invStr;
2296 			if (sLen > MAXREPLACESTRING)
2297 				goto ErrOut;
2298 
2299 			gReplaceText[0] = '\0';
2300 			strncat(gReplaceText, *invStr, sLen);
2301 
2302 			switch (mathStr[0])
2303 			{
2304 				case '-':
2305 					number = atoi(numStartStr)-atoi(operand);
2306 					break;
2307 				case '+':
2308 					number = atoi(numStartStr)+atoi(operand);
2309 					break;
2310 			}
2311 			sprintf(numberStr, "%d", number);
2312 
2313 			if ((strlen(gReplaceText) + strlen(numberStr)) > MAXREPLACESTRING)
2314 				goto ErrOut;
2315 
2316 			strcat(gReplaceText, numberStr);
2317 
2318 			while ((*numStartStr != '\0') && (*numStartStr >= '0' && *numStartStr <= '9'))
2319 				numStartStr++;
2320 
2321 			if ((strlen(gReplaceText) + strlen(numStartStr)) > MAXREPLACESTRING)
2322 				goto ErrOut;
2323 
2324 			strcat(gReplaceText, numStartStr);
2325 
2326 			*invStr = gReplaceText;
2327 		}
2328 		else
2329 		{
2330 			if ((strlen(*invStr)+strlen(operand)+1) > MAXREPLACESTRING)
2331 			{
2332 				LexError("Out of Temporary string replacement memory inside builtin macro %s\n",
2333 					invMacro->macroName);
2334 			}
2335 			else
2336 			{
2337 				sprintf(gReplaceText, "%s%s%s", *invStr, mathStr, operand);
2338 				*invStr = gReplaceText;
2339 			}
2340 		}
2341 	}
2342 
2343 
2344 	return;
2345 
2346 ErrOut:
2347 	LexError("Out of Temporary string replacement memory inside builtin macro %s\n",
2348 				invMacro->macroName);
2349 	// skip ')'
2350 	(*recognizedLen)++;
2351 }
2352 
2353 //=====================================================================
2354 // Function:	MacroIncFunction
2355 // Description:	Comes here after macro replacement is done to increment
2356 //				macro replacement string (ie, register)
2357 // Parameters:	lookStr = string after '(', so we can get parameters
2358 //				recognizedLen = # characters recoginized so far
2359 //				invStr = invoked replacement string so far
2360 // Returns:		new recognizedLen, invStr, with incremented #
2361 //=====================================================================
2362 void MacroIncFunction(char *lookStr, unsigned int *recognizedLen, char **invStr)
2363 {
2364 	MACROENTRY tMEntry;
2365 	MACROTEXT parm1;
2366 	MACROTEXT parm2;
2367 
2368 	tMEntry.macroName = (char *)"%inc()";
2369 	tMEntry.numParms = 2;
2370 	tMEntry.firstMacroParms = &parm1;
2371 	parm1.prev = NULL;
2372 	parm1.next = &parm2;
2373 	parm1.macroText = *invStr;
2374 	parm2.prev = &parm1;
2375 	parm2.next = NULL;
2376 	parm2.macroText = (char *)"1";
2377 
2378 	MacroMathFunction(&tMEntry, recognizedLen, invStr, "+");
2379 	// skip ')'
2380 	(*recognizedLen)++;
2381 }
2382 
2383 //=====================================================================
2384 // Function:	MacroDecFunction
2385 // Description:	Comes here after macro replacement is done to decrement
2386 //				macro replacement string (ie, register)
2387 // Parameters:	lookStr = string after '(', so we can get parameters
2388 //				recognizedLen = # characters recoginized so far
2389 //				invStr = invoked replacement string so far
2390 // Returns:		new recognizedLen, invStr, with decremented #
2391 //=====================================================================
2392 void MacroDecFunction(char *lookStr, unsigned int *recognizedLen, char **invStr)
2393 {
2394 	MACROENTRY tMEntry;
2395 	MACROTEXT parm1;
2396 	MACROTEXT parm2;
2397 
2398 	tMEntry.macroName = (char *)"%dec()";
2399 	tMEntry.numParms = 2;
2400 	tMEntry.firstMacroParms = &parm1;
2401 	parm1.prev = NULL;
2402 	parm1.next = &parm2;
2403 	parm1.macroText = *invStr;
2404 	parm2.prev = &parm1;
2405 	parm2.next = NULL;
2406 	parm2.macroText = (char *)"1";
2407 
2408 	MacroMathFunction(&tMEntry, recognizedLen, invStr, "-");
2409 	// skip ')'
2410 	(*recognizedLen)++;
2411 }
2412 
2413 //=====================================================================
2414 // Function:	MacroAddFunction
2415 // Description:	Comes here after macro replacement is done to add
2416 //				macro replacement string (ie, register)
2417 // Parameters:	lookStr = string after '(', so we can get parameters
2418 //				recognizedLen = # characters recoginized so far
2419 //				invStr = invoked replacement string so far
2420 // Returns:		new recognizedLen, invStr, with incremented #
2421 //=====================================================================
2422 void MacroAddFunction(char *lookStr, unsigned int *recognizedLen, char **invStr)
2423 {
2424 	MACROENTRY tMEntry;
2425 	MACROTEXT *curMT;
2426 	MACROTEXT *nextMT;
2427 	unsigned int i;
2428 
2429 	tMEntry.macroName = (char *)"%add()";
2430 	if (strlen(lookStr) > MAXREPLACESTRING)
2431 	{
2432 		LexError("Out of Temporary string replacement memory inside builtin macro %add()\n");
2433 		return;
2434 	}
2435 	if (ParseBuiltInMacroParms(&tMEntry, lookStr))
2436 	{
2437 		MacroMathFunction(&tMEntry, recognizedLen, invStr, "+");
2438 		// skip ',' strlen(parm2)+ ')'
2439 		(*recognizedLen) += strlen(tMEntry.firstMacroParms->next->macroText)+2;
2440 	}
2441 
2442 	curMT = tMEntry.firstMacroParms;
2443 	// in this case only one string was allocated
2444 	free(curMT->macroText);
2445 	for (i=0; i<tMEntry.numParms; i++)
2446 	{
2447 		nextMT = curMT->next;
2448 		free(curMT);
2449 		curMT = nextMT;
2450 	}
2451 }
2452 
2453 //=====================================================================
2454 // Function:	MacroSubFunction
2455 // Description:	Comes here after macro replacement is done to subtract
2456 //				macro replacement string (ie, register)
2457 // Parameters:	invParms, parameters that macro was invoked with
2458 //				recognizedLen = # characters recoginized so far
2459 //				invStr = invoked replacement string so far
2460 // Returns:		new recognizedLen, invStr, with incremented #
2461 //=====================================================================
2462 void MacroSubFunction(char *lookStr, unsigned int *recognizedLen, char **invStr)
2463 {
2464 	MACROENTRY tMEntry;
2465 	MACROTEXT *curMT;
2466 	MACROTEXT *nextMT;
2467 	unsigned int i;
2468 
2469 	tMEntry.macroName = (char *)"%sub()";
2470 	if (ParseBuiltInMacroParms(&tMEntry, lookStr))
2471 	{
2472 		MacroMathFunction(&tMEntry, recognizedLen, invStr, "-");
2473 		// skip ',' strlen(parm2)+ ')'
2474 		(*recognizedLen) += strlen(tMEntry.firstMacroParms->next->macroText)+2;
2475 	}
2476 	curMT = tMEntry.firstMacroParms;
2477 	// in this case only one string was allocated
2478 	free(curMT->macroText);
2479 	for (i=0; i<tMEntry.numParms; i++)
2480 	{
2481 		nextMT = curMT->next;
2482 		free(curMT);
2483 		curMT = nextMT;
2484 	}
2485 }
2486 
2487 //=====================================================================
2488 // Function:	EndMacroParms
2489 // Description:	Does update and cleanup one end of macro parameters
2490 //				is reached
2491 // Parameters:	.
2492 // Returns:		.
2493 //=====================================================================
2494 void EndMacroParms()
2495 {
2496 	char *curFileName;
2497 	char *macroFileName;
2498 	char tempStr[1024];
2499 	char *macroText;
2500 
2501 	if (gbTempInsideMacro)
2502 	{
2503 		if (gTempParseMacro->numParms != gTempMacro->numParms)
2504 		{
2505 			LexError("Macro invocation number of parameters do not match macro definition, skipping\n");
2506 			BEGIN(INITIAL);
2507 			SAFEFREE(gTempMacro);
2508 		}
2509 		else
2510 		{
2511 			// we got all the parameters for the MACRO invocation, so start inside
2512 			// the macro now, by saving off current state on stack
2513 			gIncludeStack[gIncludeStackIndex].lineNo = yylineno;
2514 			gIncludeStack[gIncludeStackIndex].fileName = gCurFileName;
2515 //			gIncludeStack[gIncludeStackIndex].fileHandle = yyin;
2516 //fprintf( stderr, "Chris fix this code with myin stuff\n" );
2517 			gIncludeStack[gIncludeStackIndex].prevString = myin;
2518 			gIncludeStack[gIncludeStackIndex].nextString = NULL;
2519 			gIncludeStack[gIncludeStackIndex].lastInvokeMacro = gInvokeMacro;
2520 			gIncludeStack[gIncludeStackIndex].lastParseMacro = gParseMacro;
2521 			gIncludeStack[gIncludeStackIndex].lastMacroLineParse = gMacroLineParse;
2522 			gIncludeStack[gIncludeStackIndex].lastbInsideMacro = gbInsideMacro;
2523 			gIncludeStack[gIncludeStackIndex].lastbInsideInclude = gbInsideInclude;
2524 			gIncludeStack[gIncludeStackIndex].buffer = YY_CURRENT_BUFFER;
2525 			gIncludeStack[gIncludeStackIndex].lastbProcessingIFDEF = gbProcessingIFDEF;
2526 			gIncludeStackIndex++;
2527 
2528 			gParseMacro = gTempParseMacro;
2529 			gInvokeMacro = gTempMacro;
2530 			gbInsideMacro = gbTempInsideMacro;
2531 
2532 			gbTempInsideMacro = false;
2533 
2534 //			yyin = NULL;
2535 			myin = NULL;
2536 			curFileName = gCurFileName;
2537 			if (curFileName == NULL)
2538 				curFileName = (char *)"";
2539 
2540 			macroFileName = gParseMacro->fileName;
2541 			if (macroFileName == NULL)
2542 				macroFileName = (char *)"";
2543 
2544 			sprintf(tempStr, "%s(%d) : References ->\n%s", curFileName, yylineno, macroFileName);
2545 			gCurFileName = strdup(tempStr);
2546 			gMacroLineParse = gParseMacro->firstMacroLines;
2547 
2548 			macroText = gMacroLine;
2549 			// if no replacement text, just use source line
2550 			if (gParseMacro->firstMacroParms == NULL)
2551 			{
2552 				macroText = gMacroLineParse->macroText;
2553 			}
2554 			else
2555 			{
2556 				// replace the macro parameters
2557 				ReplaceMacroParms(gMacroLineParse->macroText, gMacroLine, gParseMacro, gInvokeMacro);
2558 			}
2559 
2560 			yylineno = gParseMacro->lineNo;
2561 			if (gParseMacro->nLines >= 1)
2562 			{
2563 				strcpy(gSaveLine, macroText);
2564 			}
2565 
2566 //			if (gExpandMacros && (gParseMacro->nLines >= 1))
2567 //			{
2568 //				// in case there is anything there dump it out
2569 //				GenDebugLine();
2570 //				GenListString();
2571 //				if (gInvokeMacro->nLines >= 1)
2572 //					GenSwitchFileNames(macroFileName);
2573 //			}
2574 
2575 			BEGIN(gInvokeState);
2576 			yy_scan_string(macroText);
2577 			gInvokeState = INITIAL;
2578 		}
2579 	}
2580 	else
2581 	{
2582 		if (gLastMacro != NULL)
2583 		{
2584 			gLastMacro->next = gTempMacro;
2585 		}
2586 		gLastMacro = gTempMacro;
2587 		BEGIN(MACROBODY);
2588 	}
2589 }
2590 
2591 //=====================================================================
2592 // Function:	FindSwizzleValue
2593 // Description:	see if valid swizzle value and return the bits
2594 // Parameters:	swizzleTex = pointer to characters to analyze
2595 // Returns:		unsigned int = bits for swizzle values, or 0 for error
2596 //=====================================================================
2597 unsigned int FindSwizzleValue(char *swizzleText)
2598 {
2599 	unsigned int swizzleBits;
2600 	unsigned int sLen;
2601 	unsigned int i;
2602 	unsigned int lastMask;
2603 
2604 	sLen = strlen(swizzleText);
2605 	swizzleBits = 0;
2606 	lastMask = 0;
2607 
2608 	for (i=0; i<sLen; i++)
2609 	{
2610 		switch (swizzleText[i])
2611 		{
2612 		case 'x':
2613 			swizzleBits |= (WRITEMASK_X << (4*(3-i)));
2614 			lastMask = WRITEMASK_X;
2615 			break;
2616 		case 'y':
2617 			swizzleBits |= (WRITEMASK_Y << (4*(3-i)));
2618 			lastMask = WRITEMASK_Y;
2619 			break;
2620 		case 'z':
2621 			swizzleBits |= (WRITEMASK_Z << (4*(3-i)));
2622 			lastMask = WRITEMASK_Z;
2623 			break;
2624 		case 'w':
2625 			swizzleBits |= (WRITEMASK_W << (4*(3-i)));
2626 			lastMask = WRITEMASK_W;
2627 			break;
2628 		}
2629 	}
2630 
2631 	for (; i<4; i++)
2632 	{
2633 		swizzleBits |= (lastMask << (4*(3-i)));
2634 	}
2635 
2636 	return swizzleBits;
2637 }
2638 
2639 #if 0
2640 unsigned int FindSwizzleValue(char *swizzleText)
2641 {
2642 
2643 	DWORD swizzleBits;
2644 	DWORD sLen;
2645 	DWORD i;
2646 	DWORD lastIndex;
2647 
2648 	sLen = strlen(swizzleText);
2649 	swizzleBits = 0;
2650 	lastIndex = 0;
2651 
2652 	for (i=0; i<sLen; i++)
2653 	{
2654 		switch (swizzleText[i])
2655 		{
2656 		case 'x':
2657 			swizzleBits |= (0 << (D3DVS_SWIZZLE_SHIFT + (i * 2)));
2658 			lastIndex = 0;
2659 			break;
2660 		case 'y':
2661 			swizzleBits |= (1 << (D3DVS_SWIZZLE_SHIFT + (i * 2)));
2662 			lastIndex = 1;
2663 			break;
2664 		case 'z':
2665 			swizzleBits |= (2 << (D3DVS_SWIZZLE_SHIFT + (i * 2)));
2666 			lastIndex = 2;
2667 			break;
2668 		case 'w':
2669 			swizzleBits |= (3 << (D3DVS_SWIZZLE_SHIFT + (i * 2)));
2670 			lastIndex = 3;
2671 			break;
2672 		}
2673 	}
2674 
2675 	for (; i<4; i++)
2676 	{
2677 		swizzleBits |= (lastIndex << (D3DVS_SWIZZLE_SHIFT + (i * 2)));
2678 	}
2679 
2680 	return swizzleBits;
2681 
2682 
2683 }
2684 #endif
2685 
2686 //=====================================================================
2687 // Function:	FindRegisterMask
2688 // Description:	Look through register mask strings
2689 // Parameters:	findName = name to lookup
2690 // Returns:		unsigned int with token value
2691 //=====================================================================
2692 unsigned int MakeRegisterMask(char *findName)
2693 {
2694 
2695 	unsigned int regMask;
2696 	char *findFirst;
2697 
2698 	regMask = 0;
2699 
2700 	findFirst = strchr(findName, 'x');
2701 	if (findFirst != NULL)
2702 	{
2703 		if (strchr(findFirst+1, 'x') != NULL)
2704 		{
2705 			return 0;
2706 		}
2707 
2708 		regMask |= WRITEMASK_X;
2709 	}
2710 
2711 	findFirst = strchr(findName, 'y');
2712 	if (findFirst != NULL)
2713 	{
2714 		regMask |= WRITEMASK_Y;
2715 		// invalide write mask, must be swizzle
2716 		if (strchr(findFirst+1, 'x') != NULL)
2717 		{
2718 			return 0;
2719 		}
2720 
2721 		if (strchr(findFirst+1, 'y') != NULL)
2722 		{
2723 			return 0;
2724 		}
2725 
2726 	}
2727 
2728 	findFirst = strchr(findName, 'z');
2729 	if (findFirst != NULL)
2730 	{
2731 		regMask |= WRITEMASK_Z;
2732 		if (strchr(findFirst+1, 'x') != NULL)
2733 		{
2734 			return 0;
2735 		}
2736 
2737 		if (strchr(findFirst+1, 'y') != NULL)
2738 		{
2739 			return 0;
2740 		}
2741 
2742 		if (strchr(findFirst+1, 'z') != NULL)
2743 		{
2744 			return 0;
2745 		}
2746 	}
2747 
2748 	findFirst = strchr(findName, 'w');
2749 	if (findFirst != NULL)
2750 	{
2751 
2752 		regMask |= WRITEMASK_W;
2753 		if (strchr(findFirst+1, 'x') != NULL)
2754 		{
2755 			return 0;
2756 		}
2757 
2758 		if (strchr(findFirst+1, 'y') != NULL)
2759 		{
2760 			return 0;
2761 		}
2762 
2763 		if (strchr(findFirst+1, 'z') != NULL)
2764 		{
2765 			return 0;
2766 		}
2767 
2768 		if (strchr(findFirst+1, 'w') != NULL)
2769 		{
2770 			return 0;
2771 		}
2772 	}
2773 
2774 	return regMask;
2775 
2776 }
2777 
2778 //=====================================================================
2779 // Function:	LexError
2780 // Description:	output an error to the stdout
2781 // Parameters:	typical printf like format
2782 // Returns:		.
2783 //=====================================================================
2784 void LexError(const char *format, ...)
2785 {
2786 	char errstring[4096];
2787 	va_list marker;
2788 
2789 //	fprintf( stderr,"(%d) : Error : ", yylineno);
2790 	if ( gbInsideInclude )
2791 		{
2792 		sprintf( errstring, "%s", gCurFileName );
2793 		sprintf( errstring+strlen(errstring),"(%d) : Error : ", yylineno);
2794 		}
2795 	else
2796 		{
2797 		sprintf( errstring,"(%d) : Error : ", yylineno);
2798 		}
2799 
2800 	va_start(marker, format);
2801 //	vprintf(format, marker);
2802 	vsprintf(errstring+strlen(errstring), format, marker);
2803 	va_end(marker);
2804 	errors.set( errstring );
2805 }
2806 
2807 //=====================================================================
2808 // Function:	LexWarning
2809 // Description:	output a warning to the stdout
2810 // Parameters:	typical printf like format
2811 // Returns:		.
2812 //=====================================================================
2813 void LexWarning(const char *format, ...)
2814 {
2815 	char errstring[4096];
2816 	va_list marker;
2817 
2818 //	fprintf( stderr,"(%d) : warning : ", yylineno);
2819 	if ( gbInsideInclude )
2820 		sprintf( errstring, "%s", gCurFileName );
2821 	sprintf( errstring+strlen(errstring),"(%d) : Warning : ", yylineno);
2822 //	sprintf( errstring,"(%d) : Warning : ", yylineno);
2823 
2824 	va_start(marker, format);
2825 //	vprintf(format, marker);
2826 	vsprintf(errstring+strlen(errstring), format, marker);
2827 	va_end(marker);
2828 	errors.set( errstring );
2829 }
2830 
2831 //=====================================================================
2832 // Function:	DebugUnhandledState
2833 // Description:	Come here in debug mode, when a state isn't handled
2834 //				for the Lexer
2835 // Parameters:	.
2836 // Returns:		.
2837 //=====================================================================
2838 void DebugUnhandledState()
2839 {
2840 	fprintf( stderr,"Unhandled state reached, with %s text.\n", yytext);
2841 }
2842 
2843 //=====================================================================
2844 // Function:	FindOpcode
2845 // Description:	Look through opcodes and see if in the table
2846 // Parameters:	findName = name to lookup
2847 // Returns:		OPCODEMAP * = pointer to opcode map entry, if found
2848 //=====================================================================
2849 OPCODEMAP *FindOpcode(char *findName)
2850 {
2851 
2852 	unsigned i;
2853 
2854 	// just do linear search for now
2855 	for (i=0; i<NUMOPCODES; i++)
2856 	{
2857 		if (!stricmp(theOpcodes[i].string, findName))
2858 		{
2859 			return &theOpcodes[i];
2860 		}
2861 
2862 	}
2863 
2864 	return NULL;
2865 }
2866 
2867 char *ReadTextFile(const char * filename)
2868 {
2869 	char path[3][32] = { ".\0",
2870 					     "../../data/programs\0",
2871 					     "../../../data/programs\0" };
2872 	char name[8192];
2873 	int i;
2874 
2875     if (!filename) return 0;
2876 
2877     struct _stat status;
2878     int found = 0;
2879     for ( i = 0; i < 3; i++ )
2880     {
2881 	sprintf( name, "%s/%s", path[i], filename );
2882 
2883 	int fh = ::_open(name, _O_RDONLY);
2884 
2885 	if(fh != -1)
2886         {
2887             int result = _fstat( fh, &status );
2888             if( result != 0 )
2889             {
2890                 fprintf( stderr, "An fstat error occurred.\n" );
2891                 break;
2892             }
2893             ::_close( fh );
2894 	    found = i+1;
2895             break;
2896         }
2897     }
2898 
2899     if ( 0 == found )
2900 	{
2901 		fprintf(stderr,"Cannot open \"%s\" for stat read!\n", filename);
2902 		return NULL;
2903 	}
2904     long size = status.st_size;
2905 
2906     char * buf = new char[size+1];
2907 
2908 	FILE *fp = 0;
2909     if (!(fp = fopen(name, "r")))
2910 	{
2911 		fprintf(stderr,"Cannot open \"%s\" for read!\n", name);
2912 		return NULL;
2913 	}
2914 
2915 	int bytes;
2916 	bytes = fread(buf, 1, size, fp);
2917 
2918     buf[bytes] = 0;
2919 
2920 	fclose(fp);
2921 	return buf;
2922 }
2923 
2924 bool vs10_init_more();
2925 
2926 bool vs10_init(char* inputString)
2927 {
2928 	BEGIN(SAVELINE);
2929     myin = inputString;
2930 	line_incr = 0;
2931 	return vs10_init_more();
2932 }
2933 
2934 #ifndef vs10_wrap
2935 int vs10_wrap(void)
2936 {
2937   return(1);
2938 }
2939 #endif
2940