source: OGRE/trunk/ogrenew/RenderSystems/GL/src/nvparse/vs1.0_tokens.l @ 692

Revision 692, 65.1 KB checked in by mattausch, 19 years ago (diff)

adding ogre 1.2 and dependencies

Line 
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
38#define yylineno line_number
39int line_incr;
40void LexError(char *format, ...);
41void LexWarning(char *format, ...);
42char *ReadTextFile(const char * filename);
43
44unsigned int MakeRegisterMask(char *findName);
45unsigned int FindSwizzleValue(char *swizzleText);
46
47
48enum 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;
65unsigned 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
80char gReplaceText[MAXREPLACESTRING+1];
81
82//
83// forward prototypes for macro functions
84//
85void MacroIncFunction(char *, unsigned int *, char **);
86void MacroDecFunction(char *, unsigned int *, char **);
87void MacroAddFunction(char *, unsigned int *, char **);
88void MacroSubFunction(char *, unsigned int *, char **);
89
90MACROFUNCTIONS 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
100typedef 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
117INCLUDEINFO gIncludeStack[MAX_INCLUDE_DEPTH];
118int gIncludeStackIndex = 0;
119
120IFDEFINFO gIfDefStack[MAX_IFDEF_DEPTH];
121int gIfDefStackIndex = 0;
122
123unsigned int &base_linenumber = gIncludeStack[0].lineNo;
124
125bool gbInsideInclude = false;
126bool gbProcessingBuiltIn = false;
127bool gbProcessingDefine = false;
128unsigned int gCountParen = 0;
129
130bool gbProcessingIFDEF = false;
131bool gbIFDEF = false;
132bool gbCompareDefine = false;
133unsigned int gIfDefStartLine;
134
135
136MACROENTRY *gLastMacro;
137MACROENTRY *gInvokeMacro;
138MACROENTRY *gTempMacro;                                 // until all the parameters are read
139MACROENTRY *FindMacro(char *macroName);
140MACROENTRY *FindNMacro(char *macroName, unsigned int sLen);
141
142MACROFUNCTIONPTR gMacroCallFunction;
143
144char *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//
152void CleanUp();
153void ReplaceMacroParms(char *srcLine, char *destLine,
154                                                        MACROENTRY *srcParms, MACROENTRY *invParms);
155
156MACROTEXT *SaveMacroText(char *srcText, MACROTEXT *lastMacroText);
157void FreeMacroEntry(MACROENTRY *macEntry);
158void EndMacroParms();
159char *FindAlphaNum(char *srcStr, unsigned int *sLen);
160void DebugUnhandledState();
161
162
163unsigned int gCommentStartLine;
164unsigned int gMacroStartLine;
165
166char *gCurFileName = NULL;
167
168#define MAXSAVELINE 4095
169
170char gSaveLine[MAXSAVELINE+1];
171char gMacroLine[MAXSAVELINE+1];
172
173#if 1
174#ifdef _DEBUG
175#define ECHO DebugUnhandledState();
176#else
177#define ECHO
178#endif
179#endif
180
181bool gbInsideMacro = false;             // flag if we are doing a macro replace or not.
182bool gbTempInsideMacro = false;
183unsigned int gInvokeState = INITIAL;
184
185
186MACROENTRY *gParseMacro;                // which source macro entry we are using
187MACROENTRY *gTempParseMacro;    // temporary holder until parameters are received.
188MACROTEXT *gMacroLineParse;             // which line we are currently parsing inside the macro invocation
189
190typedef enum OPCODETYPE
191{
192        TYPE_NONE = 0,
193        TYPE_VERTEX_SHADER = 1,
194        TYPE_PIXEL_SHADER = 2
195};
196typedef struct OPCODEMAP
197{
198        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
214OPCODEMAP 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))
244OPCODEMAP *FindOpcode(char *findName);
245
246
247%}
248
249digits  ([0-9]+)
250digit   ([0-9])
251pt      "."
252sign            [+-]?
253exponent        ([eE]{sign}{digits})
254alpha [a-zA-Z_]
255alphadigs [a-zA-Z0-9_]
256notAlphaDigs ([^a-zA-Z0-9_])
257
258identifier              {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
295a{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
304v{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
313r{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
322c{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
331oT{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
340oD{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
349oFog[ \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
357oPos[ \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
365oPts[ \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;
505char *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        bool bFoundEndParen;
1162        unsigned int leftParenCount;
1163        unsigned int rightParenCount;
1164
1165        bFoundEndParen = false;
1166
1167        // sheesh, we gotta count the parenthesis....
1168        macroParmEnd = yytext;
1169        leftParenCount = 0;
1170        rightParenCount = 0;
1171        while (*macroParmEnd)
1172        {
1173                if (*macroParmEnd == ')')
1174                {
1175                        rightParenCount++;
1176                }
1177                if (*macroParmEnd == '(')
1178                {
1179                        leftParenCount++;
1180                }
1181
1182                macroParmEnd++;
1183        }
1184
1185        // if we found the last right parenthesis.
1186        if (rightParenCount == leftParenCount+1)
1187        {
1188                // find if we got the last parenthesis on this line
1189                macroParmEnd = strrchr(yytext, ')');
1190                yyless((macroParmEnd - yytext));
1191                BEGIN(MACROPARMEND);
1192        }
1193
1194        startOffset = strspn(yytext, " \t");
1195
1196        tMacro = SaveMacroText(&yytext[startOffset], gTempMacro->lastMacroParms);
1197        if (tMacro == NULL)
1198        {
1199                LexError("Out of memory for string table for macro parameter(s).\n");
1200                FreeMacroEntry(gTempMacro);
1201                BEGIN(EATMACRO);
1202        }
1203        else
1204        {
1205                // if first one wasn't set then set it
1206                if (gTempMacro->firstMacroParms == NULL)
1207                {
1208                        gTempMacro->firstMacroParms = tMacro;
1209                }
1210
1211                gTempMacro->lastMacroParms = tMacro;
1212
1213                gTempMacro->numParms++;
1214        }
1215
1216}
1217
1218<MACROPARMEND>")"[ \t]*"\\"*\n* {
1219        if (!gbProcessingDefine && !gbTempInsideMacro)
1220        {
1221                LexError("Malformed  macro, skipping.\n");
1222                BEGIN(EATMACRO);
1223        }
1224        else
1225        {
1226                gCountParen--;
1227
1228                // we can get multiple \n's here
1229                while (yytext[yyleng-2] == '\n')
1230                {
1231                        yyleng--;
1232                }
1233                yyless(yyleng);
1234
1235                // if there isn't a \n on this line, macro starts on this line,
1236                // not next, like in a macro definition
1237                if (yytext[yyleng-1] != '\n')
1238                {
1239                        EndMacroParms();
1240                }
1241                else
1242                {
1243                        if (yytext[yyleng-1] == '\n')
1244                        {
1245                                gTempMacro->lineNo++;
1246                        }
1247                        // count this line
1248                        gTempMacro->nLines++;
1249//                      GenDebugLine();
1250//                      GenListString();
1251                        EndMacroParms();
1252                        if (!gbInsideMacro)
1253                        {
1254                                yylineno++;
1255                        }
1256
1257                        gLinesAssembled++;
1258                }
1259
1260        }
1261}
1262
1263<MACROPARMEND>")"[ \t]*(";"|"//").*\n {
1264        if (!gbProcessingDefine && !gbTempInsideMacro)
1265        {
1266                LexError("Malformed  macro, skipping.\n");
1267                BEGIN(EATMACRO);
1268        }
1269        else
1270        {
1271
1272                // no matter what count this line
1273                gTempMacro->nLines++;
1274                gCountParen--;
1275                EndMacroParms();
1276                if (!gbInsideMacro)
1277                {
1278                        yylineno++;
1279                }
1280
1281                gLinesAssembled++;
1282        }
1283}
1284
1285<MACROPARMEND>")"[ \t]+ {
1286        if (!gbProcessingDefine && !gbTempInsideMacro)
1287        {
1288                LexError("Malformed  macro, skipping.\n");
1289                BEGIN(EATMACRO);
1290        }
1291        else
1292        {
1293                gCountParen--;
1294                if (gCountParen == 0)
1295                {
1296                        // no matter what count this line
1297                        gTempMacro->nLines++;
1298                        EndMacroParms();
1299                        if (!gbInsideMacro)
1300                        {
1301                                yylineno++;
1302                        }
1303
1304                        gLinesAssembled++;
1305                }
1306                else
1307                {
1308                        REJECT;
1309                }
1310        }
1311}
1312
1313<MACROBODY>.*"\\"[ \t]*\n {
1314        MACROTEXT *tMacro;
1315        unsigned int copyLen;
1316        char *endLine;
1317
1318        gSaveLine[0] ='\0';
1319        endLine = strchr(yytext, '\\');
1320        copyLen = (endLine - yytext);
1321        if (copyLen > MAXSAVELINE)
1322        {
1323                copyLen = MAXSAVELINE;
1324        }
1325
1326        strncat(gSaveLine, yytext, copyLen);
1327        strcat(gSaveLine, "\n");
1328        tMacro = SaveMacroText(gSaveLine, gLastMacro->lastMacroLines);
1329        if (tMacro == NULL)
1330        {
1331                LexError("Out of memory for string table for macro parameter(s).\n");
1332                BEGIN(EATDEFINE);
1333        }
1334        else
1335        {
1336                gLastMacro->nLines++;
1337                // if first one wasn't set then set it
1338                if (gLastMacro->firstMacroLines == NULL)
1339                {
1340                        gLastMacro->firstMacroLines = tMacro;
1341                }
1342
1343                gLastMacro->lastMacroLines = tMacro;
1344        }
1345
1346//      GenDebugLine();
1347//      GenListString();
1348        yylineno++;
1349        gLinesAssembled++;
1350}
1351
1352<MACROBODY>[ \t]*"endm"[ \t]*((";"|"//").*)* {
1353
1354        strncpy(gSaveLine, yytext, MAXSAVELINE);
1355        if (gbProcessingDefine)
1356        {
1357                LexError("Malformed #define, skipping.\n");
1358        }
1359
1360        BEGIN(ENDMACRO);
1361}
1362
1363<MACROBODY>[^\n]* {
1364                MACROTEXT *tMacro;
1365
1366                // check if processing #define and only one line, if not then append \n
1367                if (!gbProcessingDefine || (gLastMacro->nLines >= 1))
1368                {
1369                        gSaveLine[0] = '\0';
1370                        strncat(gSaveLine, yytext, MAXSAVELINE);
1371                        strcat(gSaveLine, "\n");
1372                        tMacro = SaveMacroText(gSaveLine, gLastMacro->lastMacroLines);
1373                        gLastMacro->nLines++;
1374                }
1375                else if (gLastMacro->numParms > 0)      // check if parameters were there
1376                {
1377                        // if so, we need the '\n' appended
1378                        gMacroLine[0] = '\0';
1379                        strncat(gMacroLine, yytext, MAXSAVELINE);
1380                        strcat(gMacroLine, "\n");
1381                        tMacro = SaveMacroText(gMacroLine, gLastMacro->lastMacroLines);
1382                        gLastMacro->nLines++;
1383                }
1384                else    // straight no newline macro replace
1385                {
1386                        tMacro = SaveMacroText(yytext, gLastMacro->lastMacroLines);
1387                }
1388
1389                if (tMacro == NULL)
1390                {
1391                        LexError("Out of memory for string table for macro parameter(s).\n");
1392                        BEGIN(EATMACRO);
1393                }
1394                else
1395                {
1396                        // if first one wasn't set then set it
1397                        if (gLastMacro->firstMacroLines == NULL)
1398                        {
1399                                gLastMacro->firstMacroLines = tMacro;
1400                        }
1401
1402                        gLastMacro->lastMacroLines = tMacro;
1403                }
1404}
1405
1406<MACROBODY>\n {
1407
1408        MACROTEXT *tMacro;
1409//      GenDebugLine();
1410//      GenListString();
1411        yylineno++;
1412        gLinesAssembled++;
1413        if (gbProcessingDefine)
1414        {
1415                gbProcessingDefine = false;
1416                BEGIN(SAVELINE);
1417        }
1418        else
1419        {
1420                // this means \n by itself inside macro body
1421                if (((yylineno-1) - gLastMacro->lineNo) !=  gLastMacro->nLines)
1422                {
1423                        strcpy(gMacroLine, "\n");
1424                        tMacro = SaveMacroText(gMacroLine, gLastMacro->lastMacroLines);
1425                        gLastMacro->nLines++;
1426
1427                        if (tMacro == NULL)
1428                        {
1429                                LexError("Out of memory for string table for macro parameter(s).\n");
1430                                BEGIN(EATMACRO);
1431                        }
1432                        else
1433                        {
1434                                // if first one wasn't set then set it
1435                                if (gLastMacro->firstMacroLines == NULL)
1436                                {
1437                                        gLastMacro->firstMacroLines = tMacro;
1438                                }
1439
1440                                gLastMacro->lastMacroLines = tMacro;
1441                        }
1442                }
1443        }
1444}
1445
1446<EATMACRO>[ \t]*"endm"[ \t]*\n {
1447        BEGIN(SAVELINE);
1448//      GenDebugLine();
1449//      GenListString();
1450        gLinesAssembled++;
1451        yylineno++;
1452}
1453
1454<EATMACRO>.*\n {
1455        strncpy(gSaveLine, yytext, MAXSAVELINE);
1456//      GenDebugLine();
1457//      GenListString();
1458        gLinesAssembled++;
1459        yylineno++;
1460}
1461
1462<EATDEFINE>.*"\\"\n {
1463        strncpy(gSaveLine, yytext, MAXSAVELINE);
1464//      GenDebugLine();
1465//      GenListString();
1466        gLinesAssembled++;
1467        yylineno++;
1468}
1469
1470<EATDEFINE>.*\n {
1471        strncpy(gSaveLine, yytext, MAXSAVELINE);
1472//      GenDebugLine();
1473//      GenListString();
1474        gLinesAssembled++;
1475        yylineno++;
1476        BEGIN(SAVELINE);
1477}
1478
1479<INITIAL,MODIFIER>{alpha}{alphadigs}* {
1480
1481        gTempParseMacro = FindMacro(yytext);
1482
1483        if (gTempParseMacro != NULL)
1484        {
1485                if (gIncludeStackIndex >= MAX_INCLUDE_DEPTH )
1486                {
1487                        LexError("macros nested too deeply");
1488                        exit( 1 );
1489                }
1490
1491                if (gTempParseMacro->firstMacroLines != NULL)
1492                {
1493
1494                        gTempMacro = (MACROENTRY *)malloc(sizeof(MACROENTRY));
1495                        if (gTempMacro == NULL)
1496                        {
1497                                LexError("Out of memory allocating MACROENTRY structure.\n");
1498                        }
1499                        else
1500                        {
1501
1502                                gTempMacro->next = NULL;
1503                                gTempMacro->prev = NULL;
1504                                gTempMacro->macroName = NULL;
1505                                gTempMacro->firstMacroParms = NULL;
1506                                gTempMacro->lastMacroParms = NULL;
1507                                gTempMacro->firstMacroLines = NULL;
1508                                gTempMacro->lastMacroLines = NULL;
1509                                gTempMacro->numParms = 0;
1510                                gTempMacro->nLines = 0;
1511
1512                                gbTempInsideMacro = true;               // flag we are currently doing a macro replace.
1513                                gInvokeState = YYSTATE;
1514                                if (gTempParseMacro->numParms > 0)
1515                                {
1516                                        BEGIN(MACROPARMSTART);
1517                                }
1518                                else
1519                                {
1520                                        EndMacroParms();
1521                                        gbTempInsideMacro = false;      // no longer waiting for macro invocation
1522                                }                               
1523                        }
1524                }
1525        }
1526        else
1527        {
1528                BEGIN(INITIAL);
1529                REJECT;
1530        }
1531}
1532
1533[,\[\]\-\+\(\)\*\<\>\/\%_\.] {
1534//    fprintf( stderr, "%c ", yytext[0] );
1535        return yytext[0];
1536}
1537
1538
1539[ \t]+  {}
1540
1541<DEFINE>\n {
1542        LexError("Didn't find label string for #define.\n");
1543        BEGIN(SAVELINE);
1544//      return '\n';
1545}
1546
1547"\n" {
1548//fprintf(stderr, "\n");
1549//      line_incr = 1;
1550        line_incr++;
1551        BEGIN(SAVELINE);
1552        return '\n';
1553}
1554
1555<EATSTRING>{alphadigs}+ {
1556        BEGIN(INITIAL);
1557//      fprintf( stderr, "%s", yytext );
1558        if (yyleng == 1)
1559                return yytext[0];
1560        else
1561                LexError("Unrecognized Token: %s\n", yytext);
1562        return UNKNOWN_STRING;
1563}
1564
1565<EATSTRING>[\001-\040]          {
1566//      vs10_lval.ival = yytext[0];
1567        LexError("Illegal character: %d decimal.\n", yytext[0]);
1568        return(ILLEGAL);
1569}
1570
1571[\001-\040]             {
1572//      vs10_lval.ival = yytext[0];
1573        LexError("Illegal character: %d decimal.\n", yytext[0]);
1574        return(ILLEGAL);
1575}
1576
1577<EATSTRING>. {
1578        return yytext[0];
1579}
1580
1581. {
1582        BEGIN(EATSTRING);
1583        yyless(0);
1584}
1585
1586<<EOF>> {
1587        bool wasInMacro;
1588        bool oneLiner;
1589        char *macroText;
1590
1591        wasInMacro = gbInsideMacro;
1592        oneLiner = false;
1593
1594
1595        // if we are inside the macro then do next line until their are no more
1596        if (gbInsideMacro)
1597        {
1598                oneLiner = (gParseMacro->nLines == 0);
1599
1600                // free the temporary parameter replaced line we were working on.
1601                // get next line in macro text, if any
1602                gMacroLineParse = gMacroLineParse->next;
1603                // more lines to parse?
1604                if (gMacroLineParse != NULL)
1605                {
1606                        macroText = gMacroLine;
1607                        // if no replacement text, just use source line
1608                        if (gParseMacro->firstMacroParms == NULL)
1609                        {
1610                                macroText = gMacroLineParse->macroText;
1611                        }
1612                        else
1613                        {
1614                                // replace the macro parameters
1615                                ReplaceMacroParms(gMacroLineParse->macroText, gMacroLine, gParseMacro, gInvokeMacro);
1616                        }
1617
1618//                      if (gExpandMacros)
1619//                      {
1620//                              strcpy(gSaveLine, macroText);
1621//                      }
1622
1623                        BEGIN(INITIAL);
1624                        // and lex it.
1625                        yy_scan_string(macroText);
1626                }
1627                else
1628                {
1629                        // no more lines in this macro, so free the working macro
1630                        SAFEFREE(gInvokeMacro);
1631                        // shut off flag for inside a macro replacement state.
1632                        gbInsideMacro = false;
1633                }
1634        }
1635
1636        if (gbProcessingIFDEF && !wasInMacro)
1637        {
1638                LexError("End of file reached before #endif found, macro started on line %d.\n", gIfDefStartLine);
1639        }
1640
1641        if (!gbInsideMacro)
1642        {
1643                if ( gIncludeStackIndex == 0 )
1644                {
1645                        if (!gbProcessingBuiltIn)
1646                                CleanUp();
1647                        return 0;
1648//                      return TOKEN_EOF;
1649                }
1650                else
1651                {
1652                        yy_delete_buffer( YY_CURRENT_BUFFER );
1653                        SAFEFREE(gCurFileName);
1654//                      SAFEDELETE(myin);
1655//                      SAFECLOSE(yyin);
1656                }
1657
1658                gIncludeStackIndex--;
1659                SAFEDELETEARRAY( gIncludeStack[gIncludeStackIndex].nextString );
1660                yy_switch_to_buffer(gIncludeStack[gIncludeStackIndex].buffer );
1661                gCurFileName = gIncludeStack[gIncludeStackIndex].fileName;
1662//              yyin = gIncludeStack[gIncludeStackIndex].fileHandle;
1663                myin = gIncludeStack[gIncludeStackIndex].prevString;
1664                yylineno = gIncludeStack[gIncludeStackIndex].lineNo;
1665                gInvokeMacro = gIncludeStack[gIncludeStackIndex].lastInvokeMacro;
1666                gParseMacro = gIncludeStack[gIncludeStackIndex].lastParseMacro;
1667                gMacroLineParse = gIncludeStack[gIncludeStackIndex].lastMacroLineParse;
1668                gbInsideInclude = gIncludeStack[gIncludeStackIndex].lastbInsideInclude;
1669                gbInsideMacro = gIncludeStack[gIncludeStackIndex].lastbInsideMacro;
1670                gbProcessingIFDEF = gIncludeStack[gIncludeStackIndex].lastbProcessingIFDEF;
1671
1672                if (!gbInsideMacro && !oneLiner)
1673                {
1674//                      GenSwitchFileNames(gCurFileName);
1675                        BEGIN(SAVELINE);
1676                }
1677                else
1678                {
1679                        BEGIN(INITIAL);
1680                }
1681
1682                // gSaveLine was last line saved, before macro invocation
1683                if (wasInMacro && !gbInsideMacro && !oneLiner)
1684                {
1685//                      GenDebugLine();
1686//                      GenListString();
1687                        gLinesAssembled++;
1688                        yylineno++;
1689                }
1690
1691        }
1692
1693}
1694
1695%%
1696
1697
1698//=====================================================================
1699// Function:    FindNMacro
1700// Description: Look through macros and see if it had been predefined
1701// Parameters:  findName = name to lookup
1702//                              sLen = # characters valid in source (findName)
1703// Returns:             MACROENTRY * = pointer to macro entry if found
1704//=====================================================================
1705MACROENTRY *FindNMacro(char *findName, unsigned int sLen)
1706{
1707        MACROENTRY *curEntry;
1708
1709        curEntry = gLastMacro;
1710        while (curEntry != NULL)
1711        {
1712                if (strlen(curEntry->macroName) == sLen)
1713                {
1714                        if (!strncmp(curEntry->macroName, findName, sLen))
1715                        {
1716                                break;
1717                        }
1718                }
1719
1720                curEntry = curEntry->prev;
1721        }
1722
1723        return curEntry;
1724       
1725}
1726
1727//=====================================================================
1728// Function:    FindMacro
1729// Description: Look through macros and see if it had been predefined
1730// Parameters:  findName = name to lookup
1731// Returns:             MACROENTRY * = pointer to macro entry if found
1732//=====================================================================
1733MACROENTRY *FindMacro(char *findName)
1734{
1735        MACROENTRY *curEntry;
1736
1737        curEntry = gLastMacro;
1738        while (curEntry != NULL)
1739        {
1740                if (!strcmp(curEntry->macroName, findName))
1741                {
1742                        break;
1743                }
1744
1745                curEntry = curEntry->prev;
1746        }
1747
1748        return curEntry;
1749       
1750}
1751
1752//=====================================================================
1753// Function:    CleanUp
1754// Description: Clean up the #define strings
1755// Parameters:  .
1756// Returns:             .
1757//=====================================================================
1758void CleanUp()
1759{
1760        void *tPtr;
1761
1762        // free up the macros that were alloced
1763        while (gLastMacro != NULL)
1764        {
1765
1766                FreeMacroEntry(gLastMacro);
1767
1768                tPtr = gLastMacro;
1769                gLastMacro = gLastMacro->prev;
1770                SAFEFREE(tPtr);
1771        }
1772
1773}
1774
1775//=====================================================================
1776// Function:    FreeMacroEntry
1777// Description: Frees up the macro entry data, (parms, lines of text)
1778// Parameters:  macEntry = pointer to the MACROENTRY structure
1779// Returns:             .
1780//=====================================================================
1781void FreeMacroEntry(MACROENTRY *macEntry)
1782{
1783        MACROTEXT *tText;
1784        MACROTEXT *tNext;
1785
1786        SAFEFREE(macEntry->macroName);
1787        SAFEFREE(macEntry->fileName);
1788        // free the macro lines that were alloced
1789        tText = macEntry->lastMacroLines;
1790        while (tText != NULL)
1791        {
1792                tNext = tText->prev;
1793                SAFEFREE(tText);
1794                tText = tNext;
1795        }
1796
1797        // free the text of the macro parms that were alloced
1798        tText = macEntry->lastMacroParms;
1799        while (tText != NULL)
1800        {
1801                tNext = tText->prev;
1802                SAFEFREE(tText);
1803                tText = tNext;
1804        }
1805}
1806
1807//=====================================================================
1808// Function:    CheckMacroFunctions
1809// Description: Find if this text is a builtin macro function
1810// Parameters:  lookString = non-null terminated string of possible
1811//                              and if found set global macro function call
1812// Returns:             .
1813//=====================================================================
1814void CheckMacroFunctions(char *lookString, unsigned int *recognizedLen, char **invString)
1815{
1816
1817        unsigned int i;
1818        unsigned int sLen;
1819       
1820        for (i=0; i< NUM_MACRO_FUNCTIONS; i++)
1821        {
1822                sLen = strlen(gMacroFunctions[i].name);
1823                if (!strncmp(gMacroFunctions[i].name, lookString, sLen))
1824                {
1825                        gMacroCallFunction = gMacroFunctions[i].function;
1826                        *recognizedLen = sLen;
1827                        *invString = NULL;
1828                        return;
1829                }
1830        }
1831}
1832
1833//=====================================================================
1834// Function:    FindAlphaNum
1835// Description: Find a whole alpha numeric string, ie consists of
1836//                              [A-Za-z0-9_] only
1837// Parameters:  srcStr = source string to search through.
1838//                              sLen = unsinged int pointer to length of string found
1839// Returns:             pointer to found start of string.
1840//                              NULL if none.
1841//=====================================================================
1842char *FindAlphaNum(char *srcStr, unsigned int *sLen)
1843{
1844        char curChar;
1845        char *foundStr;
1846
1847        while (*srcStr != '\0')
1848        {
1849                curChar = toupper(*srcStr);
1850                if ((curChar >= 'A') && (curChar <= 'Z'))
1851                        break;
1852
1853                if ((curChar >= '0') && (curChar <='9'))
1854                        break;
1855
1856                if (curChar == '_')
1857                        break;
1858
1859                srcStr++;
1860        }
1861
1862        if (*srcStr == '\0')
1863        {
1864                return NULL;
1865        }
1866
1867        foundStr = srcStr;
1868
1869        *sLen = 0;
1870        // now search for end of string of [A-Za-z0-9_]
1871        while (*srcStr != '\0')
1872        {
1873                curChar = toupper(*srcStr);
1874                if ((curChar < 'A') || (curChar > 'Z'))
1875                {
1876                        if ((curChar < '0') || (curChar > '9'))
1877                        {
1878                                if (curChar != '_')
1879                                        break;
1880                        }
1881                }
1882
1883                (*sLen)++;
1884                srcStr++;
1885        }
1886
1887        return foundStr;
1888
1889}
1890
1891//=====================================================================
1892// Function:    FindDefineParm
1893// Description: Find if the MACROENTRY->macroText linked list contains
1894//                              replaceable parameters.
1895// Parameters:  srcParms = pointer to MACROENTRY structure for source
1896//                                              parameters
1897//                              invParms = MACROENTRY pointer to invocation parameters
1898//                              lookString = non-null terminated string of possible
1899//                                                      replaceable string
1900//                              recognizedLen = replacement string matched length
1901//                              invString = invocation string to replace with
1902// Returns:             pointer to first character found in lookstring
1903//=====================================================================
1904char *FindDefineParm(MACROENTRY *srcParms, MACROENTRY *invParms,
1905                                                char *lookString, unsigned int *recognizedLen, char **invString)
1906{
1907        MACROTEXT *srcText;
1908        MACROTEXT *invText;
1909        char *checkStr;
1910        unsigned int checkLen;
1911        unsigned int sLen;
1912
1913        checkStr = lookString;
1914        *invString = NULL;
1915
1916        // first search for first [A-Za-z0-9_] only string
1917        checkStr = FindAlphaNum(lookString, &checkLen);
1918
1919        while (checkStr != NULL)
1920        {
1921                // check all the #define parameters for match
1922                srcText = srcParms->firstMacroParms;
1923                invText = invParms->firstMacroParms;
1924                while (srcText)
1925                {
1926                        sLen = strlen(srcText->macroText);
1927                        // lengths should match
1928                        if (sLen == checkLen)
1929                        {
1930                                if (!strncmp(checkStr, srcText->macroText, checkLen))
1931                                {
1932                                        // it matched so return replacement text
1933                                        *invString = invText->macroText;
1934                                        // and length that we reconized
1935                                        *recognizedLen = checkLen;
1936                                        return checkStr;
1937                                }
1938                        }
1939
1940                        srcText = srcText->next;
1941                        invText = invText->next;
1942                }
1943
1944                // not found yet, so go to next string.
1945                checkStr = FindAlphaNum(checkStr+checkLen, &checkLen);
1946        }
1947
1948        return NULL;
1949}
1950
1951//=====================================================================
1952// Function:    FindReplaceParm
1953// Description: Find if the MACROENTRY->macroText linked list contains
1954//                              a replaceable parameters.
1955// Parameters:  srcParms = pointer to MACROENTRY structure for source
1956//                                              parameters
1957//                              invParms = MACROENTRY pointer to invocation parameters
1958//                              lookString = non-null terminated string of possible
1959//                                                      replaceable string
1960//                              recognizedLen = replacement string matched length
1961//                              invString = invocation string to replace with
1962// Returns:             .
1963//=====================================================================
1964void FindReplaceParm(MACROENTRY *srcParms, MACROENTRY *invParms,
1965                                                char *lookString, unsigned int *recognizedLen, char **invString)
1966{
1967        unsigned int sLen;
1968        MACROTEXT *srcText;
1969        MACROTEXT *invText;
1970
1971        *recognizedLen = 0;
1972        *invString = NULL;
1973
1974        srcText = srcParms->firstMacroParms;
1975        invText = invParms->firstMacroParms;
1976
1977        if (srcText != NULL)
1978        {
1979                // go until srcText # strings ends
1980                while (srcText != NULL)
1981                {
1982                        sLen = strlen(srcText->macroText);
1983                        if (!strncmp(srcText->macroText, lookString, sLen))
1984                        {
1985                                // found it so return src, replacement string
1986                                *recognizedLen = strlen(srcText->macroText);
1987                                *invString = invText->macroText;
1988                                // call function macro if it was invoked prior.
1989                                if (gMacroCallFunction != NULL)
1990                                {
1991                                        gMacroCallFunction(lookString, recognizedLen, invString);
1992                                        gMacroCallFunction = NULL;
1993                                }
1994                                return;
1995                        }
1996
1997                        srcText = srcText->next;
1998                        invText = invText->next;
1999                }
2000        }
2001
2002        // ok, it wasn't found, look through builtin macro functions
2003        CheckMacroFunctions(lookString, recognizedLen, invString);
2004}
2005
2006//=====================================================================
2007// Function:    ReplaceMacroParms
2008// Description: Replace macro parameters when macro was defined, with
2009//                              those specified on the macro invocation line
2010// Parameters:  srcLine = source line to replace src macro parms with
2011//                              destLine = destination line save to.
2012//                              invocation macro parameters.
2013//                              parseMacro = currently parsing macro entry
2014//                              invParms = invocation macro entry
2015// Returns:             .
2016//=====================================================================
2017void ReplaceMacroParms(char *srcLine, char *destLine,
2018                                                        MACROENTRY *srcParms, MACROENTRY *invParms)
2019{
2020        char *findReplace;
2021        char *invString;
2022        unsigned int sLen;
2023        unsigned int dLen;
2024        unsigned int copyLen;
2025        unsigned int subLen;
2026        unsigned int recognizedLen;
2027
2028        destLine[0]= '\0';
2029
2030        sLen = strlen(srcLine);
2031        dLen = 0;
2032
2033        while (sLen > 0)
2034        {
2035                // strtok might work better except it modifies the string, so
2036                // kind of do my own....
2037                if (!srcParms->bIsDefine)
2038                {
2039                        findReplace = strchr(srcLine, '%');
2040                        if (findReplace != NULL)
2041                        {
2042                                // bypass % sign in findReplacement
2043                                findReplace++;
2044                                // figure out length of source before %
2045                                copyLen = (findReplace - srcLine)-1;
2046                                // check if there is a replacement string
2047                                FindReplaceParm(srcParms, invParms, findReplace, &recognizedLen, &invString);
2048                        }
2049                        else
2050                        {
2051                                strcat(destLine, srcLine);
2052                                return;
2053                        }
2054                }
2055                else
2056                {
2057                        findReplace = FindDefineParm(srcParms, invParms, srcLine, &recognizedLen, &invString);
2058                        if (findReplace != NULL)
2059                        {
2060                                // figure out length of source before %
2061                                copyLen = findReplace - srcLine;
2062                        }
2063                        else
2064                        {
2065                                strcat(destLine, srcLine);
2066                                return;
2067                        }
2068                }
2069
2070
2071                if (invString != NULL)
2072                {
2073                        // figure out how much we are going to substitute
2074                        subLen = strlen(invString);
2075                }
2076                else
2077                {
2078                        subLen = 0;
2079                }
2080
2081                if ((dLen + copyLen + subLen) > MAXSAVELINE)
2082                {
2083                        LexError("Macro string overrun.\n");
2084                        CleanUp();
2085                        exit(ERROR_MACRO_OVERRUN);
2086                }
2087
2088                if (copyLen > 0)
2089                {
2090                        strncat(destLine, srcLine, copyLen);
2091                        dLen += copyLen;
2092                }
2093
2094                srcLine += copyLen;
2095                sLen -= copyLen;
2096                // in macro so skip % part of variable
2097                if (!srcParms->bIsDefine)
2098                {
2099                        // skip %, also
2100                        srcLine++;
2101                        sLen--;
2102                }
2103
2104                if (invString != NULL)
2105                {
2106                        strcat(destLine, invString);
2107                        dLen += strlen(invString);
2108                }
2109
2110                srcLine += recognizedLen;
2111                sLen -= recognizedLen;
2112        }
2113
2114}
2115
2116//=====================================================================
2117// Function:    SaveMacroText
2118// Description: Adds a string to a linked list of MACROTEXT structures
2119// Parameters:  srcText = pointer to source text to save
2120//                              lastMacroText = last allocated, or NULL
2121// Returns:             newly allocated MACROTEXT structure, or NULL
2122//=====================================================================
2123MACROTEXT *SaveMacroText(char *srcText, MACROTEXT *lastMacroText)
2124{
2125        MACROTEXT *curMacroText;
2126
2127        curMacroText = (MACROTEXT *)malloc(sizeof(MACROTEXT));
2128        if (curMacroText == NULL)
2129        {
2130                return NULL;
2131        }
2132        else
2133        {
2134                // no next entry but set up previous with previously alloced macro parameter
2135                curMacroText->next = NULL;
2136                curMacroText->prev = lastMacroText;
2137
2138                // if the macroParm pointer is null then we are the first allocated
2139                // so if not set the last one allocate next pointer to newly allocated structure
2140                if (lastMacroText != NULL)
2141                {
2142                        lastMacroText->next = curMacroText;
2143                }
2144
2145                /* %%%%% this should be set up in memory pools. */
2146                curMacroText->macroText = strdup(srcText);
2147                if (curMacroText->macroText == NULL)
2148                {
2149                        SAFEFREE(curMacroText);
2150                        return NULL;
2151                }
2152        }
2153
2154        return curMacroText;
2155}
2156
2157//=====================================================================
2158// Function:    ParseBuiltInMacroParms
2159// Description: parse parameters of string and fill in MACROENTRY
2160//                              structure.
2161// Parameters:  parsedMacro = pointer to MACROENTRY structure that gets
2162//                              filled in with parameter pointers and count
2163//                              parmStr = string to parse parameters from
2164// Returns:             false if error
2165//=====================================================================
2166bool ParseBuiltInMacroParms(MACROENTRY *parsedMacro, char *parmStr)
2167{
2168        char *endStr;
2169        char *foundParm;
2170        MACROTEXT *prevMT;
2171        MACROTEXT *curMT;
2172
2173        parsedMacro->numParms = 0;
2174        parsedMacro->firstMacroParms = NULL;
2175       
2176        foundParm = strdup(parmStr);
2177        if (foundParm == NULL)
2178        {
2179                LexError("Out of memory parsing bultin macro parameters.\n");
2180                return false;
2181        }
2182
2183        // assume a ')' is on the end.
2184        endStr = strrchr(foundParm, ')');
2185        if (endStr == NULL)
2186        {
2187                LexWarning("Ending parenthesis not found for macro %s.\n", parsedMacro->macroName);
2188                endStr = foundParm + strlen(foundParm);
2189        }
2190
2191        prevMT = NULL;
2192        // strip out and seperate parameters
2193        while (foundParm < endStr)
2194        {
2195                // allocate a macro text structure
2196                curMT = (MACROTEXT *)malloc(sizeof(MACROTEXT));
2197                if (curMT == NULL)
2198                {
2199                        free(parmStr);
2200                        LexError("Out of memory parsing bultin macro parameters.\n");
2201                        return false;
2202                }
2203                curMT->next = NULL;
2204                curMT->prev = prevMT;
2205                parsedMacro->numParms++;
2206
2207                if (prevMT != NULL)
2208                {
2209                        prevMT->next = curMT;
2210                }
2211                else
2212                {
2213                        parsedMacro->firstMacroParms = curMT;
2214                }
2215
2216                curMT->macroText = foundParm;
2217                // search for next parameters, delimited by comma
2218                foundParm = strchr(foundParm, ',');
2219                if (foundParm == NULL)
2220                {
2221                        foundParm = endStr;
2222                        *foundParm = '\0';
2223                }
2224                else
2225                {
2226                        // skip comma
2227                        *foundParm = '\0';
2228                        foundParm++;
2229                }
2230                prevMT = curMT;
2231        }
2232
2233        return true;
2234}
2235
2236//=====================================================================
2237// Function:    MacroMathFunction
2238// Description: Comes here after macro replacement is done to perform
2239//                              some mathematic function on parameter (macro replacement
2240//                               string (ie, register))
2241// Parameters:  invMacro = macroentry pointer containing macro information
2242//                              recognizedLen = # characters recoginized so far
2243//                              invStr = invoked replacement string so far
2244//                              mathStr = "-", "+", etc for mathematic function
2245// Returns:             new recognizedLen, invStr, with incremented #
2246//=====================================================================
2247void MacroMathFunction(MACROENTRY *invMacro, unsigned int *recognizedLen, char **invStr,
2248                                                char *mathStr)
2249{
2250        char *numStartStr;
2251        unsigned int sLen;
2252        char numberStr[256];
2253        unsigned int number;
2254        char *operand;
2255
2256
2257        // verify enough paramters to complete operation
2258        if (invMacro->numParms != 2)
2259        {
2260                LexError("Two parameters are required for %s macro\n", invMacro->macroName);
2261                return;
2262        }
2263
2264        // get second macro parm, which is add by amount.
2265        operand = invMacro->firstMacroParms->next->macroText;
2266
2267        // first find inner most bracket if any
2268        numStartStr = strrchr(*invStr, ']');
2269        if (numStartStr == NULL)
2270        {
2271                numStartStr = strrchr(*invStr, ')');
2272        }
2273
2274        if (numStartStr != NULL)
2275        {
2276                if ((strlen(*invStr)+strlen(operand)+1) > MAXREPLACESTRING)
2277                {
2278                        LexError("Out of Temporary string replacement memory inside builtin macro %s\n",
2279                                        invMacro->macroName);
2280                }
2281                else
2282                {
2283                        sLen = (numStartStr - *invStr);
2284                        gReplaceText[0] = '\0';
2285                        strncat(gReplaceText, *invStr, sLen);
2286                        strcat(gReplaceText, mathStr);
2287                        strcat(gReplaceText, operand);
2288                        strcat(gReplaceText, numStartStr);
2289                        *invStr = gReplaceText;
2290                }
2291        }
2292        else
2293        {
2294                numStartStr = strpbrk(*invStr, "0123456789");
2295                if (numStartStr != NULL)
2296                {
2297                        // put up to number we found
2298                        sLen = numStartStr - *invStr;
2299                        if (sLen > MAXREPLACESTRING)
2300                                goto ErrOut;
2301
2302                        gReplaceText[0] = '\0';
2303                        strncat(gReplaceText, *invStr, sLen);
2304
2305                        switch (mathStr[0])
2306                        {
2307                                case '-':
2308                                        number = atoi(numStartStr)-atoi(operand);
2309                                        break;
2310                                case '+':
2311                                        number = atoi(numStartStr)+atoi(operand);
2312                                        break;
2313                        }
2314                        sprintf(numberStr, "%d", number);
2315
2316                        if ((strlen(gReplaceText) + strlen(numberStr)) > MAXREPLACESTRING)
2317                                goto ErrOut;
2318
2319                        strcat(gReplaceText, numberStr);
2320
2321                        while ((*numStartStr != '\0') && (*numStartStr >= '0' && *numStartStr <= '9'))
2322                                numStartStr++;
2323
2324                        if ((strlen(gReplaceText) + strlen(numStartStr)) > MAXREPLACESTRING)
2325                                goto ErrOut;
2326
2327                        strcat(gReplaceText, numStartStr);
2328
2329                        *invStr = gReplaceText;
2330                }
2331                else
2332                {
2333                        if ((strlen(*invStr)+strlen(operand)+1) > MAXREPLACESTRING)
2334                        {
2335                                LexError("Out of Temporary string replacement memory inside builtin macro %s\n",
2336                                        invMacro->macroName);
2337                        }
2338                        else
2339                        {
2340                                sprintf(gReplaceText, "%s%s%s", *invStr, mathStr, operand);
2341                                *invStr = gReplaceText;
2342                        }
2343                }
2344        }
2345
2346
2347        return;
2348
2349ErrOut:
2350        LexError("Out of Temporary string replacement memory inside builtin macro %s\n",
2351                                invMacro->macroName);
2352        // skip ')'
2353        (*recognizedLen)++;
2354}
2355
2356//=====================================================================
2357// Function:    MacroIncFunction
2358// Description: Comes here after macro replacement is done to increment
2359//                              macro replacement string (ie, register)
2360// Parameters:  lookStr = string after '(', so we can get parameters
2361//                              recognizedLen = # characters recoginized so far
2362//                              invStr = invoked replacement string so far
2363// Returns:             new recognizedLen, invStr, with incremented #
2364//=====================================================================
2365void MacroIncFunction(char *lookStr, unsigned int *recognizedLen, char **invStr)
2366{
2367        MACROENTRY tMEntry;
2368        MACROTEXT parm1;
2369        MACROTEXT parm2;
2370
2371        tMEntry.macroName = "%inc()";
2372        tMEntry.numParms = 2;
2373        tMEntry.firstMacroParms = &parm1;
2374        parm1.prev = NULL;
2375        parm1.next = &parm2;
2376        parm1.macroText = *invStr;
2377        parm2.prev = &parm1;
2378        parm2.next = NULL;
2379        parm2.macroText = "1";
2380
2381        MacroMathFunction(&tMEntry, recognizedLen, invStr, "+");
2382        // skip ')'
2383        (*recognizedLen)++;
2384}
2385
2386//=====================================================================
2387// Function:    MacroDecFunction
2388// Description: Comes here after macro replacement is done to decrement
2389//                              macro replacement string (ie, register)
2390// Parameters:  lookStr = string after '(', so we can get parameters
2391//                              recognizedLen = # characters recoginized so far
2392//                              invStr = invoked replacement string so far
2393// Returns:             new recognizedLen, invStr, with decremented #
2394//=====================================================================
2395void MacroDecFunction(char *lookStr, unsigned int *recognizedLen, char **invStr)
2396{
2397        MACROENTRY tMEntry;
2398        MACROTEXT parm1;
2399        MACROTEXT parm2;
2400
2401        tMEntry.macroName = "%dec()";
2402        tMEntry.numParms = 2;
2403        tMEntry.firstMacroParms = &parm1;
2404        parm1.prev = NULL;
2405        parm1.next = &parm2;
2406        parm1.macroText = *invStr;
2407        parm2.prev = &parm1;
2408        parm2.next = NULL;
2409        parm2.macroText = "1";
2410
2411        MacroMathFunction(&tMEntry, recognizedLen, invStr, "-");
2412        // skip ')'
2413        (*recognizedLen)++;
2414}
2415
2416//=====================================================================
2417// Function:    MacroAddFunction
2418// Description: Comes here after macro replacement is done to add
2419//                              macro replacement string (ie, register)
2420// Parameters:  lookStr = string after '(', so we can get parameters
2421//                              recognizedLen = # characters recoginized so far
2422//                              invStr = invoked replacement string so far
2423// Returns:             new recognizedLen, invStr, with incremented #
2424//=====================================================================
2425void MacroAddFunction(char *lookStr, unsigned int *recognizedLen, char **invStr)
2426{
2427        MACROENTRY tMEntry;
2428        MACROTEXT *curMT;
2429        MACROTEXT *nextMT;
2430        unsigned int i;
2431
2432        tMEntry.macroName = "%add()";
2433        if (strlen(lookStr) > MAXREPLACESTRING)
2434        {
2435                LexError("Out of Temporary string replacement memory inside builtin macro %add()\n");
2436                return;
2437        }
2438        if (ParseBuiltInMacroParms(&tMEntry, lookStr))
2439        {
2440                MacroMathFunction(&tMEntry, recognizedLen, invStr, "+");
2441                // skip ',' strlen(parm2)+ ')'
2442                (*recognizedLen) += strlen(tMEntry.firstMacroParms->next->macroText)+2;
2443        }
2444
2445        curMT = tMEntry.firstMacroParms;
2446        // in this case only one string was allocated
2447        free(curMT->macroText);
2448        for (i=0; i<tMEntry.numParms; i++)
2449        {
2450                nextMT = curMT->next;
2451                free(curMT);
2452                curMT = nextMT;
2453        }
2454}
2455
2456//=====================================================================
2457// Function:    MacroSubFunction
2458// Description: Comes here after macro replacement is done to subtract
2459//                              macro replacement string (ie, register)
2460// Parameters:  invParms, parameters that macro was invoked with
2461//                              recognizedLen = # characters recoginized so far
2462//                              invStr = invoked replacement string so far
2463// Returns:             new recognizedLen, invStr, with incremented #
2464//=====================================================================
2465void MacroSubFunction(char *lookStr, unsigned int *recognizedLen, char **invStr)
2466{
2467        MACROENTRY tMEntry;
2468        MACROTEXT *curMT;
2469        MACROTEXT *nextMT;
2470        unsigned int i;
2471
2472        tMEntry.macroName = "%sub()";
2473        if (ParseBuiltInMacroParms(&tMEntry, lookStr))
2474        {
2475                MacroMathFunction(&tMEntry, recognizedLen, invStr, "-");
2476                // skip ',' strlen(parm2)+ ')'
2477                (*recognizedLen) += strlen(tMEntry.firstMacroParms->next->macroText)+2;
2478        }
2479        curMT = tMEntry.firstMacroParms;
2480        // in this case only one string was allocated
2481        free(curMT->macroText);
2482        for (i=0; i<tMEntry.numParms; i++)
2483        {
2484                nextMT = curMT->next;
2485                free(curMT);
2486                curMT = nextMT;
2487        }
2488}
2489
2490//=====================================================================
2491// Function:    EndMacroParms
2492// Description: Does update and cleanup one end of macro parameters
2493//                              is reached
2494// Parameters:  .
2495// Returns:             .
2496//=====================================================================
2497void EndMacroParms()
2498{
2499        char *curFileName;
2500        char *macroFileName;
2501        char tempStr[1024];
2502        char *macroText;
2503
2504        if (gbTempInsideMacro)
2505        {
2506                if (gTempParseMacro->numParms != gTempMacro->numParms)
2507                {
2508                        LexError("Macro invocation number of parameters do not match macro definition, skipping\n");
2509                        BEGIN(INITIAL);
2510                        SAFEFREE(gTempMacro);
2511                }
2512                else
2513                {
2514                        // we got all the parameters for the MACRO invocation, so start inside
2515                        // the macro now, by saving off current state on stack
2516                        gIncludeStack[gIncludeStackIndex].lineNo = yylineno;
2517                        gIncludeStack[gIncludeStackIndex].fileName = gCurFileName;
2518//                      gIncludeStack[gIncludeStackIndex].fileHandle = yyin;
2519//fprintf( stderr, "Chris fix this code with myin stuff\n" );
2520                        gIncludeStack[gIncludeStackIndex].prevString = myin;
2521                        gIncludeStack[gIncludeStackIndex].nextString = NULL;
2522                        gIncludeStack[gIncludeStackIndex].lastInvokeMacro = gInvokeMacro;
2523                        gIncludeStack[gIncludeStackIndex].lastParseMacro = gParseMacro;
2524                        gIncludeStack[gIncludeStackIndex].lastMacroLineParse = gMacroLineParse;
2525                        gIncludeStack[gIncludeStackIndex].lastbInsideMacro = gbInsideMacro;
2526                        gIncludeStack[gIncludeStackIndex].lastbInsideInclude = gbInsideInclude;
2527                        gIncludeStack[gIncludeStackIndex].buffer = YY_CURRENT_BUFFER;
2528                        gIncludeStack[gIncludeStackIndex].lastbProcessingIFDEF = gbProcessingIFDEF;
2529                        gIncludeStackIndex++;
2530
2531                        gParseMacro = gTempParseMacro;
2532                        gInvokeMacro = gTempMacro;
2533                        gbInsideMacro = gbTempInsideMacro;
2534
2535                        gbTempInsideMacro = false;
2536
2537//                      yyin = NULL;
2538                        myin = NULL;
2539                        curFileName = gCurFileName;
2540                        if (curFileName == NULL)
2541                                curFileName = "";
2542
2543                        macroFileName = gParseMacro->fileName;
2544                        if (macroFileName == NULL)
2545                                macroFileName = "";
2546
2547                        sprintf(tempStr, "%s(%d) : References ->\n%s", curFileName, yylineno, macroFileName);
2548                        gCurFileName = strdup(tempStr);
2549                        gMacroLineParse = gParseMacro->firstMacroLines;
2550
2551                        macroText = gMacroLine;
2552                        // if no replacement text, just use source line
2553                        if (gParseMacro->firstMacroParms == NULL)
2554                        {
2555                                macroText = gMacroLineParse->macroText;
2556                        }
2557                        else
2558                        {
2559                                // replace the macro parameters
2560                                ReplaceMacroParms(gMacroLineParse->macroText, gMacroLine, gParseMacro, gInvokeMacro);
2561                        }
2562
2563                        yylineno = gParseMacro->lineNo;
2564                        if (gParseMacro->nLines >= 1)
2565                        {
2566                                strcpy(gSaveLine, macroText);
2567                        }
2568
2569//                      if (gExpandMacros && (gParseMacro->nLines >= 1))
2570//                      {
2571//                              // in case there is anything there dump it out
2572//                              GenDebugLine();
2573//                              GenListString();                       
2574//                              if (gInvokeMacro->nLines >= 1)
2575//                                      GenSwitchFileNames(macroFileName);
2576//                      }
2577
2578                        BEGIN(gInvokeState);
2579                        yy_scan_string(macroText);
2580                        gInvokeState = INITIAL;
2581                }
2582        }
2583        else
2584        {
2585                if (gLastMacro != NULL)
2586                {
2587                        gLastMacro->next = gTempMacro;
2588                }
2589                gLastMacro = gTempMacro;
2590                BEGIN(MACROBODY);
2591        }
2592}
2593
2594//=====================================================================
2595// Function:    FindSwizzleValue
2596// Description: see if valid swizzle value and return the bits
2597// Parameters:  swizzleTex = pointer to characters to analyze
2598// Returns:             unsigned int = bits for swizzle values, or 0 for error
2599//=====================================================================
2600unsigned int FindSwizzleValue(char *swizzleText)
2601{
2602        unsigned int swizzleBits;
2603        unsigned int sLen;
2604        unsigned int i;
2605        unsigned int lastMask;
2606
2607        sLen = strlen(swizzleText);
2608        swizzleBits = 0;
2609        lastMask = 0;
2610
2611        for (i=0; i<sLen; i++)
2612        {
2613                switch (swizzleText[i])
2614                {
2615                case 'x':
2616                        swizzleBits |= (WRITEMASK_X << (4*(3-i)));
2617                        lastMask = WRITEMASK_X;
2618                        break;
2619                case 'y':
2620                        swizzleBits |= (WRITEMASK_Y << (4*(3-i)));
2621                        lastMask = WRITEMASK_Y;
2622                        break;
2623                case 'z':
2624                        swizzleBits |= (WRITEMASK_Z << (4*(3-i)));
2625                        lastMask = WRITEMASK_Z;
2626                        break;
2627                case 'w':
2628                        swizzleBits |= (WRITEMASK_W << (4*(3-i)));
2629                        lastMask = WRITEMASK_W;
2630                        break;
2631                }
2632        }
2633
2634        for (; i<4; i++)
2635        {
2636                swizzleBits |= (lastMask << (4*(3-i)));
2637        }
2638
2639        return swizzleBits;
2640}
2641
2642#if 0
2643unsigned int FindSwizzleValue(char *swizzleText)
2644{
2645
2646        DWORD swizzleBits;
2647        DWORD sLen;
2648        DWORD i;
2649        DWORD lastIndex;
2650
2651        sLen = strlen(swizzleText);
2652        swizzleBits = 0;
2653        lastIndex = 0;
2654
2655        for (i=0; i<sLen; i++)
2656        {
2657                switch (swizzleText[i])
2658                {
2659                case 'x':
2660                        swizzleBits |= (0 << (D3DVS_SWIZZLE_SHIFT + (i * 2)));
2661                        lastIndex = 0;
2662                        break;
2663                case 'y':
2664                        swizzleBits |= (1 << (D3DVS_SWIZZLE_SHIFT + (i * 2)));
2665                        lastIndex = 1;
2666                        break;
2667                case 'z':
2668                        swizzleBits |= (2 << (D3DVS_SWIZZLE_SHIFT + (i * 2)));
2669                        lastIndex = 2;
2670                        break;
2671                case 'w':
2672                        swizzleBits |= (3 << (D3DVS_SWIZZLE_SHIFT + (i * 2)));
2673                        lastIndex = 3;
2674                        break;
2675                }
2676        }
2677
2678        for (; i<4; i++)
2679        {
2680                swizzleBits |= (lastIndex << (D3DVS_SWIZZLE_SHIFT + (i * 2)));
2681        }
2682
2683        return swizzleBits;
2684
2685       
2686}
2687#endif
2688
2689//=====================================================================
2690// Function:    FindRegisterMask
2691// Description: Look through register mask strings
2692// Parameters:  findName = name to lookup
2693// Returns:             unsigned int with token value
2694//=====================================================================
2695unsigned int MakeRegisterMask(char *findName)
2696{
2697
2698        unsigned int regMask;
2699        char *findFirst;
2700
2701        regMask = 0;
2702
2703        findFirst = strchr(findName, 'x');
2704        if (findFirst != NULL)
2705        {
2706                if (strchr(findFirst+1, 'x') != NULL)
2707                {
2708                        return 0;
2709                }
2710
2711                regMask |= WRITEMASK_X;
2712        }
2713
2714        findFirst = strchr(findName, 'y');
2715        if (findFirst != NULL)
2716        {
2717                regMask |= WRITEMASK_Y;
2718                // invalide write mask, must be swizzle
2719                if (strchr(findFirst+1, 'x') != NULL)
2720                {
2721                        return 0;
2722                }
2723
2724                if (strchr(findFirst+1, 'y') != NULL)
2725                {
2726                        return 0;
2727                }
2728
2729        }
2730
2731        findFirst = strchr(findName, 'z');
2732        if (findFirst != NULL)
2733        {
2734                regMask |= WRITEMASK_Z;
2735                if (strchr(findFirst+1, 'x') != NULL)
2736                {
2737                        return 0;
2738                }
2739
2740                if (strchr(findFirst+1, 'y') != NULL)
2741                {
2742                        return 0;
2743                }
2744
2745                if (strchr(findFirst+1, 'z') != NULL)
2746                {
2747                        return 0;
2748                }
2749        }
2750
2751        findFirst = strchr(findName, 'w');
2752        if (findFirst != NULL)
2753        {
2754
2755                regMask |= WRITEMASK_W;
2756                if (strchr(findFirst+1, 'x') != NULL)
2757                {
2758                        return 0;
2759                }
2760
2761                if (strchr(findFirst+1, 'y') != NULL)
2762                {
2763                        return 0;
2764                }
2765
2766                if (strchr(findFirst+1, 'z') != NULL)
2767                {
2768                        return 0;
2769                }
2770
2771                if (strchr(findFirst+1, 'w') != NULL)
2772                {
2773                        return 0;
2774                }
2775        }
2776
2777        return regMask;
2778       
2779}
2780
2781//=====================================================================
2782// Function:    LexError
2783// Description: output an error to the stdout
2784// Parameters:  typical printf like format
2785// Returns:             .
2786//=====================================================================
2787void LexError(char *format, ...)
2788{
2789        char errstring[4096];
2790        va_list marker;
2791
2792//      fprintf( stderr,"(%d) : Error : ", yylineno);
2793        if ( gbInsideInclude )
2794                {
2795                sprintf( errstring, "%s", gCurFileName );
2796                sprintf( errstring+strlen(errstring),"(%d) : Error : ", yylineno);
2797                }
2798        else
2799                {
2800                sprintf( errstring,"(%d) : Error : ", yylineno);
2801                }
2802
2803        va_start(marker, format);
2804//      vprintf(format, marker);
2805        vsprintf(errstring+strlen(errstring), format, marker);
2806        va_end(marker);
2807        errors.set( errstring );
2808}
2809
2810//=====================================================================
2811// Function:    LexWarning
2812// Description: output a warning to the stdout
2813// Parameters:  typical printf like format
2814// Returns:             .
2815//=====================================================================
2816void LexWarning(char *format, ...)
2817{
2818        char errstring[4096];
2819        va_list marker;
2820
2821//      fprintf( stderr,"(%d) : warning : ", yylineno);
2822        if ( gbInsideInclude )
2823                sprintf( errstring, "%s", gCurFileName );
2824        sprintf( errstring+strlen(errstring),"(%d) : Warning : ", yylineno);
2825//      sprintf( errstring,"(%d) : Warning : ", yylineno);
2826
2827        va_start(marker, format);
2828//      vprintf(format, marker);
2829        vsprintf(errstring+strlen(errstring), format, marker);
2830        va_end(marker);
2831        errors.set( errstring );
2832}
2833
2834//=====================================================================
2835// Function:    DebugUnhandledState
2836// Description: Come here in debug mode, when a state isn't handled
2837//                              for the Lexer
2838// Parameters:  .
2839// Returns:             .
2840//=====================================================================
2841void DebugUnhandledState()
2842{
2843        fprintf( stderr,"Unhandled state reached, with %s text.\n", yytext);
2844}
2845
2846//=====================================================================
2847// Function:    FindOpcode
2848// Description: Look through opcodes and see if in the table
2849// Parameters:  findName = name to lookup
2850// Returns:             OPCODEMAP * = pointer to opcode map entry, if found
2851//=====================================================================
2852OPCODEMAP *FindOpcode(char *findName)
2853{
2854
2855        unsigned i;
2856
2857        // just do linear search for now
2858        for (i=0; i<NUMOPCODES; i++)
2859        {
2860                if (!stricmp(theOpcodes[i].string, findName))
2861                {
2862                        return &theOpcodes[i];
2863                }
2864
2865        }
2866
2867        return NULL;
2868}
2869
2870char *ReadTextFile(const char * filename)
2871{
2872        char path[3][32] = { ".\0",
2873                                             "../../data/programs\0",
2874                                             "../../../data/programs\0" };
2875        char name[8192];
2876        int i;
2877
2878    if (!filename) return 0;
2879
2880    struct _stat status;
2881    int found = 0;
2882    for ( i = 0; i < 3; i++ )
2883    {
2884        sprintf( name, "%s/%s", path[i], filename );
2885
2886        int fh = ::_open(name, _O_RDONLY);
2887
2888        if(fh != -1)
2889        {
2890            int result = _fstat( fh, &status );
2891            if( result != 0 )
2892            {
2893                fprintf( stderr, "An fstat error occurred.\n" );
2894                break;
2895            }
2896            ::_close( fh );
2897            found = i+1;
2898            break;
2899        }
2900    }
2901
2902    if ( 0 == found )
2903        {
2904                fprintf(stderr,"Cannot open \"%s\" for stat read!\n", filename);
2905                return NULL;
2906        }
2907    long size = status.st_size;
2908
2909    char * buf = new char[size+1];
2910
2911        FILE *fp = 0;
2912    if (!(fp = fopen(name, "r")))
2913        {
2914                fprintf(stderr,"Cannot open \"%s\" for read!\n", name);
2915                return NULL;
2916        }
2917
2918        int bytes;
2919        bytes = fread(buf, 1, size, fp);
2920
2921    buf[bytes] = 0;
2922
2923        fclose(fp);
2924        return buf;
2925}
2926
2927bool vs10_init_more();
2928
2929bool vs10_init(char* inputString)
2930{
2931        BEGIN(SAVELINE);
2932    myin = inputString;
2933        line_incr = 0;
2934        return vs10_init_more();
2935}
2936
2937#ifndef vs10_wrap
2938int vs10_wrap(void)
2939{
2940  return(1);
2941}
2942#endif
Note: See TracBrowser for help on using the repository browser.