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