| 544 | } |
| 545 | |
| 546 | void PreprocessLineDirectives(rdcarray<ShaderSourceFile> &sourceFiles) |
| 547 | { |
| 548 | struct SplitFile |
| 549 | { |
| 550 | rdcstr filename; |
| 551 | rdcarray<rdcstr> lines; |
| 552 | bool modified = false; |
| 553 | }; |
| 554 | |
| 555 | rdcarray<SplitFile> splitFiles; |
| 556 | |
| 557 | splitFiles.resize(sourceFiles.size()); |
| 558 | |
| 559 | for(size_t i = 0; i < sourceFiles.size(); i++) |
| 560 | splitFiles[i].filename = sourceFiles[i].filename; |
| 561 | |
| 562 | for(size_t i = 0; i < sourceFiles.size(); i++) |
| 563 | { |
| 564 | rdcarray<rdcstr> srclines; |
| 565 | |
| 566 | // start off writing to the corresponding output file. |
| 567 | SplitFile *dstFile = &splitFiles[i]; |
| 568 | bool changedFile = false; |
| 569 | |
| 570 | size_t dstLine = 0; |
| 571 | |
| 572 | // skip this file if it doesn't contain #line |
| 573 | if(!sourceFiles[i].contents.contains("#line")) |
| 574 | continue; |
| 575 | |
| 576 | split(sourceFiles[i].contents, srclines, '\n'); |
| 577 | srclines.push_back(""); |
| 578 | |
| 579 | // handle #line directives by inserting empty lines or erasing as necessary |
| 580 | bool seenLine = false; |
| 581 | |
| 582 | for(size_t srcLine = 0; srcLine < srclines.size(); srcLine++) |
| 583 | { |
| 584 | if(srclines[srcLine].empty()) |
| 585 | { |
| 586 | dstLine++; |
| 587 | continue; |
| 588 | } |
| 589 | |
| 590 | char *c = &srclines[srcLine][0]; |
| 591 | char *end = c + srclines[srcLine].size(); |
| 592 | |
| 593 | while(*c == '\t' || *c == ' ' || *c == '\r') |
| 594 | c++; |
| 595 | |
| 596 | if(c == end) |
| 597 | { |
| 598 | // blank line, just advance line counter |
| 599 | dstLine++; |
| 600 | continue; |
| 601 | } |
| 602 | |
| 603 | if(c + 5 > end || strncmp(c, "#line", 5) != 0) |