@@ -17,8 +17,12 @@ ASSERTNAME
1717RTCLASS (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
2327uint16_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