Skip to content

Commit a8a1352

Browse files
committed
kauai/src/lex.cpp: read gcc pre-processor soure file information from input file
When processing an input file, lex.cpp uses the embedded pre-processor source file information to track the current file and line position. The MSVC pre-processor generates source file information in the form "#line <num> <filename>" whilst the gcc pre-processor generates source file information in the form "# <n> <filename> <flags>". Adjust LEXB::_FSkipWhiteSpace() so that it can handle both MSVC and gcc embedded pre-processor source file information.
1 parent 1325758 commit a8a1352

1 file changed

Lines changed: 174 additions & 66 deletions

File tree

kauai/src/lex.cpp

Lines changed: 174 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,12 @@ ASSERTNAME
1717
RTCLASS(LEXB)
1818

1919
// #line handling
20-
achar _szPoundLine[] = PszLit("#line");
21-
#define kcchPoundLine (CvFromRgv(_szPoundLine) - 1)
20+
achar _szMsvcPoundLine[] = PszLit("#line");
21+
#define kcchMsvcPoundLine (CvFromRgv(_szMsvcPoundLine) - 1)
22+
23+
// #<space> handling
24+
achar _szGccPoundLine[] = PszLit("# ");
25+
#define kcchGccPoundLine (CvFromRgv(_szGccPoundLine) - 1)
2226

2327
uint16_t LEXB::_mpchgrfct[128] = {
2428
// 0x00 - 0x07
@@ -461,9 +465,9 @@ bool LEXB::_FSkipWhiteSpace(void)
461465
{
462466
AssertThis(0);
463467
achar ch;
464-
bool fStar, fSkipComment, fSlash;
468+
bool fStar, fSkipComment, fSlash, fCppMs, fCppGcc;
465469
int32_t lwLineSav;
466-
achar rgch[kcchPoundLine + 1];
470+
achar rgch[kcchMsvcPoundLine + 1];
467471
STN stn;
468472

469473
fSkipComment = fFalse;
@@ -517,83 +521,187 @@ bool LEXB::_FSkipWhiteSpace(void)
517521
}
518522
}
519523

520-
// if this is at the beginning of a line, check for a #line directive
521-
if (!_fLineStart || (ch != _szPoundLine[0]) || !_FFetchRgch(rgch, kcchPoundLine + 1) ||
522-
!FEqualRgb(rgch, _szPoundLine, kcchPoundLine) || !(_GrfctCh(rgch[kcchPoundLine]) & fctSpc))
524+
// if this is at the beginning of a line, check for a pre-processor directive
525+
fCppMs = fFalse;
526+
fCppGcc = fFalse;
527+
if (_fLineStart && (ch == _szMsvcPoundLine[0]) && _FFetchRgch(rgch, 2))
528+
{
529+
// check for #line directive (msvc)
530+
if (FEqualRgb(rgch, _szMsvcPoundLine, 2) && _FFetchRgch(rgch, kcchMsvcPoundLine + 1) &&
531+
(_GrfctCh(rgch[kcchMsvcPoundLine]) & fctSpc))
532+
fCppMs = fTrue;
533+
534+
// check for #<space> directive (gcc)
535+
if (FEqualRgb(rgch, _szGccPoundLine, 2) && _FFetchRgch(rgch, kcchGccPoundLine) &&
536+
(_GrfctCh(rgch[kcchGccPoundLine - 1]) & fctSpc))
537+
fCppGcc = fTrue;
538+
539+
if (fCppMs == fFalse && fCppGcc == fFalse)
540+
{
541+
_fLineStart = fFalse;
542+
break;
543+
}
544+
}
545+
else
523546
{
524547
_fLineStart = fFalse;
525548
break;
526549
}
527550

528-
// a #line directive - skip it and white space
529-
_Advance(kcchPoundLine);
530-
while (_FFetchRgch(&ch) && (_GrfctCh(ch) & fctSpc) && ch != kchReturn)
531-
_Advance();
551+
if (fCppMs == fTrue)
552+
{
553+
// a #line directive - skip it and white space
554+
_Advance(kcchMsvcPoundLine);
555+
while (_FFetchRgch(&ch) && (_GrfctCh(ch) & fctSpc) && ch != kchReturn)
556+
_Advance();
532557

533-
// read the line number
534-
lwLineSav = _lwLine;
535-
if (!_FFetchRgch(&ch) || !(_GrfctCh(ch) & fctDec))
536-
goto LBadDirective;
537-
_Advance();
538-
_ReadNumber(&_lwLine, ch, 10, klwMax);
539-
_lwLine--;
540-
541-
// skip white space (and make sure there is some)
542-
if (!_FFetchRgch(&ch))
543-
break; // eof
544-
if (!(_GrfctCh(ch) & fctSpc))
545-
goto LBadDirective;
546-
while (_FFetchRgch(&ch) && (_GrfctCh(ch) & fctSpc) && ch != kchReturn)
558+
// read the line number
559+
lwLineSav = _lwLine;
560+
if (!_FFetchRgch(&ch) || !(_GrfctCh(ch) & fctDec))
561+
goto LBadDirective;
547562
_Advance();
548-
if (!_FFetchRgch(&ch))
549-
break; // eof
550-
if (ch == kchReturn)
551-
continue; // end of #line
552-
553-
// read file name
554-
if (ch != ChLit('"'))
555-
goto LBadDirective;
556-
_Advance();
557-
stn.SetNil();
558-
for (fSlash = fFalse;;)
559-
{
560-
if (!_FFetchRgch(&ch) || ch == kchReturn)
563+
_ReadNumber(&_lwLine, ch, 10, klwMax);
564+
_lwLine--;
565+
566+
// skip white space (and make sure there is some)
567+
if (!_FFetchRgch(&ch))
568+
break; // eof
569+
if (!(_GrfctCh(ch) & fctSpc))
570+
goto LBadDirective;
571+
while (_FFetchRgch(&ch) && (_GrfctCh(ch) & fctSpc) && ch != kchReturn)
572+
_Advance();
573+
if (!_FFetchRgch(&ch))
574+
break; // eof
575+
if (ch == kchReturn)
576+
continue; // end of #line
577+
578+
// read file name
579+
if (ch != ChLit('"'))
561580
goto LBadDirective;
562581
_Advance();
563-
if (ch == ChLit('"'))
564-
break;
565-
if (ch == ChLit('\\'))
582+
stn.SetNil();
583+
for (fSlash = fFalse;;)
584+
{
585+
if (!_FFetchRgch(&ch) || ch == kchReturn)
586+
goto LBadDirective;
587+
_Advance();
588+
if (ch == ChLit('"'))
589+
break;
590+
if (ch == ChLit('\\'))
591+
{
592+
// if this is the second of a pair of slashes, skip it
593+
fSlash = !fSlash;
594+
if (!fSlash)
595+
continue;
596+
}
597+
else
598+
fSlash = fFalse;
599+
stn.FAppendCh(ch);
600+
}
601+
602+
// skip white space to end of line
603+
if (!_FFetchRgch(&ch))
604+
goto LSetFileName; // eof
605+
if (!(_GrfctCh(ch) & fctSpc))
606+
goto LBadDirective;
607+
while (_FFetchRgch(&ch) && (_GrfctCh(ch) & fctSpc) && ch != kchReturn)
608+
_Advance();
609+
if (!_FFetchRgch(&ch))
610+
goto LSetFileName; // eof
611+
if (ch != kchReturn)
566612
{
567-
// if this is the second of a pair of slashes, skip it
568-
fSlash = !fSlash;
569-
if (!fSlash)
570-
continue;
613+
LBadDirective:
614+
// Bad #line directive - restore the line number
615+
_lwLine = lwLineSav;
616+
return fFalse;
571617
}
572618
else
573-
fSlash = fFalse;
574-
stn.FAppendCh(ch);
619+
{
620+
LSetFileName:
621+
_stnFile = stn;
622+
}
575623
}
576624

577-
// skip white space to end of line
578-
if (!_FFetchRgch(&ch))
579-
goto LSetFileName; // eof
580-
if (!(_GrfctCh(ch) & fctSpc))
581-
goto LBadDirective;
582-
while (_FFetchRgch(&ch) && (_GrfctCh(ch) & fctSpc) && ch != kchReturn)
583-
_Advance();
584-
if (!_FFetchRgch(&ch))
585-
goto LSetFileName; // eof
586-
if (ch != kchReturn)
587-
{
588-
LBadDirective:
589-
// Bad #line directive - restore the line number
590-
_lwLine = lwLineSav;
591-
return fFalse;
592-
}
593-
else
625+
if (fCppGcc == fTrue)
594626
{
595-
LSetFileName:
596-
_stnFile = stn;
627+
// a #<space> directive - skip it and white space
628+
_Advance(kcchGccPoundLine);
629+
while (_FFetchRgch(&ch) && (_GrfctCh(ch) & fctSpc) && ch != kchReturn && ch != kchLineFeed)
630+
_Advance();
631+
632+
// read the line number
633+
lwLineSav = _lwLine;
634+
if (!_FFetchRgch(&ch) || !(_GrfctCh(ch) & fctDec))
635+
goto LBadDirective;
636+
_Advance();
637+
_ReadNumber(&_lwLine, ch, 10, klwMax);
638+
if (_lwLine)
639+
_lwLine--;
640+
641+
// skip white space (and make sure there is some)
642+
if (!_FFetchRgch(&ch))
643+
break; // eof
644+
if (!(_GrfctCh(ch) & fctSpc))
645+
goto LBadDirective;
646+
while (_FFetchRgch(&ch) && (_GrfctCh(ch) & fctSpc) && ch != kchReturn && ch != kchLineFeed)
647+
_Advance();
648+
if (!_FFetchRgch(&ch))
649+
break; // eof
650+
if (ch == kchReturn || ch == kchLineFeed)
651+
continue; // end of #<space>
652+
653+
// read file name
654+
if (ch != ChLit('"'))
655+
goto LBadDirective;
656+
_Advance();
657+
stn.SetNil();
658+
for (fSlash = fFalse;;)
659+
{
660+
if (!_FFetchRgch(&ch) || ch == kchReturn || ch == kchLineFeed)
661+
goto LBadDirective2;
662+
_Advance();
663+
if (ch == ChLit('"'))
664+
break;
665+
if (ch == ChLit('\\'))
666+
{
667+
// if this is the second of a pair of slashes, skip it
668+
fSlash = !fSlash;
669+
if (!fSlash)
670+
continue;
671+
}
672+
else
673+
fSlash = fFalse;
674+
stn.FAppendCh(ch);
675+
}
676+
677+
// if end of line, no flags
678+
if (!_FFetchRgch(&ch))
679+
goto LSetFileName2; // eof
680+
if (!(_GrfctCh(ch) & fctSpc))
681+
goto LBadDirective2;
682+
if (ch == kchReturn || ch == kchLineFeed)
683+
{
684+
goto LSetFileName2; // no flags
685+
}
686+
// fetch up until end of line
687+
while (_FFetchRgch(&ch) && ((_GrfctCh(ch) & fctSpc) || (_GrfctCh(ch) & fctDec)) && ch != kchReturn &&
688+
ch != kchLineFeed)
689+
_Advance();
690+
if (!_FFetchRgch(&ch))
691+
goto LSetFileName; // eof
692+
693+
if (ch != kchReturn && ch != kchLineFeed)
694+
{
695+
LBadDirective2:
696+
// Bad #<space> directive - restore the line number
697+
_lwLine = lwLineSav;
698+
return fFalse;
699+
}
700+
else
701+
{
702+
LSetFileName2:
703+
_stnFile = stn;
704+
}
597705
}
598706
}
599707

0 commit comments

Comments
 (0)