@@ -87,6 +87,7 @@ struct FileState
8787 YY_BUFFER_STATE bufState = 0 ;
8888 QCString fileName;
8989 bool lexRulesPart = false ;
90+ BoolStack levelGuard;
9091};
9192
9293struct PreIncludeInfo
@@ -297,6 +298,10 @@ struct preYY_state
297298 IntMap argMap;
298299 BoolStack levelGuard;
299300 std::stack< std::unique_ptr<preYY_CondCtx> > condStack;
301+ int condGuardCount;
302+ QCString condGuardErrorFileName;
303+ int condGuardErrorLine;
304+ QCString condGuardErrorMessage;
300305 std::deque< std::unique_ptr<FileState> > includeStack;
301306 std::unordered_map<std::string,Define*> expandedDict;
302307 StringUnorderedSet expanded;
@@ -1678,6 +1683,7 @@ NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER}
16781683 yyextra->ccomment =FALSE ;
16791684 }
16801685 yyextra->condCtx =YY_START ;
1686+ yyextra->condGuardCount =0 ;
16811687 startCondSection (yyscanner," " );
16821688 BEGIN (SkipCond);
16831689 }
@@ -1692,7 +1698,9 @@ NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER}
16921698 }
16931699
16941700<SkipCond>. { }
1695- <SkipCond>[^\/\!*\\@\n]+ { }
1701+ <SkipCond>" #if" (" def" )? { yyextra->condGuardCount ++; }
1702+ <SkipCond>" #endif" { yyextra->condGuardCount --; }
1703+ <SkipCond>[^\/\!*\\@\n#]+ { }
16961704<SkipCond>{CPPC }[/!] { yyextra->ccomment =FALSE ; }
16971705<SkipCond>{CCS }[*!] { yyextra->ccomment =TRUE ; }
16981706<SkipCond,SkipCComment,SkipCPPComment>{CMD }{CMD }" endcond" /[^a-z_A-Z0 -9 \x80-\xFF] {
@@ -2091,6 +2099,17 @@ NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER}
20912099 }
20922100 else
20932101 {
2102+ if (!yyextra->levelGuard.empty())
2103+ {
2104+ if (yyextra->condGuardErrorLine!=0)
2105+ {
2106+ warn(yyextra->condGuardErrorFileName,yyextra->condGuardErrorLine," {}" ,yyextra->condGuardErrorMessage);
2107+ }
2108+ else
2109+ {
2110+ warn(yyextra->fileName,yyextra->yyLineNr," More #endif' s than #if' s found." );
2111+ }
2112+ }
20942113 QCString toFileName = yyextra->fileName;
20952114 const std::unique_ptr<FileState> &fs=yyextra->includeStack.back();
20962115 //fileDefineCache->merge(yyextra->fileName,fs->fileName);
@@ -2102,6 +2121,7 @@ NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER}
21022121 yyextra->inputBuf = fs->oldFileBuf;
21032122 yyextra->inputBufPos = fs->oldFileBufPos;
21042123 yyextra->curlyCount = fs->curlyCount;
2124+ yyextra->levelGuard = fs->levelGuard;
21052125 setFileName(yyscanner,fs->fileName);
21062126 TRACE(" switching to {}" ,yyextra->fileName);
21072127
@@ -2253,20 +2273,27 @@ static void incrLevel(yyscan_t yyscanner)
22532273{
22542274 YY_EXTRA_TYPE state = preYYget_extra(yyscanner);
22552275 state->levelGuard.push(false );
2256- // printf("%s line %d: incrLevel %d \n",qPrint(yyextra ->fileName),yyextra ->yyLineNr,yyextra ->levelGuard.size());
2276+ // printf("%s line %d: incrLevel %zu \n",qPrint(state ->fileName),state ->yyLineNr,state ->levelGuard.size());
22572277}
22582278
22592279static void decrLevel (yyscan_t yyscanner)
22602280{
22612281 YY_EXTRA_TYPE state = preYYget_extra(yyscanner);
2262- // printf("%s line %d: decrLevel %d \n",qPrint(state->fileName),state->yyLineNr,state->levelGuard.size());
2282+ // printf("%s line %d: decrLevel %zu \n",qPrint(state->fileName),state->yyLineNr,state->levelGuard.size());
22632283 if (!state->levelGuard.empty())
22642284 {
22652285 state->levelGuard .pop ();
22662286 }
22672287 else
22682288 {
2269- warn (state->fileName ,state->yyLineNr ," More #endif's than #if's found." );
2289+ if (state->condGuardErrorLine !=0 )
2290+ {
2291+ warn (state->condGuardErrorFileName ,state->condGuardErrorLine ," {}" ,state->condGuardErrorMessage );
2292+ }
2293+ else
2294+ {
2295+ warn (state->fileName ,state->yyLineNr ," More #endif's than #if's found." );
2296+ }
22702297 }
22712298}
22722299
@@ -3802,6 +3829,8 @@ static void readIncludeFile(yyscan_t yyscanner,const QCString &inc)
38023829 fs->curlyCount = state->curlyCount;
38033830 //state->curlyCount = 0; // don't reset counter, see issue #10997
38043831 fs->lexRulesPart = state->lexRulesPart;
3832+ fs->levelGuard = state->levelGuard;
3833+ while (!state->levelGuard.empty()) state->levelGuard.pop();
38053834 state->lexRulesPart = false;
38063835 // push the state on the stack
38073836 FileState *fs_ptr = fs.get();
@@ -3890,6 +3919,22 @@ static void startCondSection(yyscan_t yyscanner,const QCString §Id)
38903919static void endCondSection (yyscan_t yyscanner)
38913920{
38923921 YY_EXTRA_TYPE state = preYYget_extra(yyscanner);
3922+ if (state->condGuardCount>0 && state->condGuardErrorLine==0 )
3923+ {
3924+ state->condGuardErrorLine = state->yyLineNr ;
3925+ state->condGuardErrorFileName = state->fileName ;
3926+ state->condGuardErrorMessage = " more #if's than #endif's in \\ cond..\\ endcond section" ;
3927+ }
3928+ else if (state->condGuardCount<0 && state->condGuardErrorLine==0 )
3929+ {
3930+ state->condGuardErrorLine = state->yyLineNr ;
3931+ state->condGuardErrorFileName = state->fileName ;
3932+ state->condGuardErrorMessage = " more #endif's than #if's in \\ cond..\\ endcond section" ;
3933+ }
3934+ else // balanced again -> no error
3935+ {
3936+ state->condGuardErrorLine = 0 ;
3937+ }
38933938 if (state->condStack.empty())
38943939 {
38953940 warn (state->fileName ,state->yyLineNr ," the \\ endcond does not have a corresponding \\ cond in this file" );
@@ -4221,6 +4266,9 @@ void Preprocessor::processFile(const QCString &fileName,const std::string &input
42214266 state->expandedDict.clear();
42224267 state->contextDefines.clear();
42234268 state->pragmaSet.clear();
4269+ state->condGuardCount=0 ;
4270+ state->condGuardErrorLine=0 ;
4271+ while (!state->levelGuard.empty()) state->levelGuard.pop();
42244272 while (!state->condStack.empty()) state->condStack.pop();
42254273
42264274 setFileName(yyscanner,fileName);
@@ -4257,7 +4305,14 @@ void Preprocessor::processFile(const QCString &fileName,const std::string &input
42574305
42584306 if (!state->levelGuard.empty())
42594307 {
4260- warn (state->fileName ,state->yyLineNr ," More #if's than #endif's found (might be in an included file)." );
4308+ if (yyextra->condGuardErrorLine !=0 )
4309+ {
4310+ warn (yyextra->condGuardErrorFileName ,yyextra->condGuardErrorLine ," {}" ,yyextra->condGuardErrorMessage );
4311+ }
4312+ else
4313+ {
4314+ warn (state->fileName ,state->yyLineNr ," More #if's than #endif's found (might be in an included file)." );
4315+ }
42614316 }
42624317
42634318 if (Debug::isFlagSet(Debug::Preprocessor))
0 commit comments