summaryrefslogtreecommitdiff
path: root/src/pre.l
diff options
context:
space:
mode:
Diffstat (limited to 'src/pre.l')
-rw-r--r--src/pre.l233
1 files changed, 151 insertions, 82 deletions
diff --git a/src/pre.l b/src/pre.l
index ff04162..e36d1ec 100644
--- a/src/pre.l
+++ b/src/pre.l
@@ -109,7 +109,7 @@ struct PreIncludeInfo
};
/** A dictionary of managed Define objects. */
-typedef std::map< std::string,std::unique_ptr<Define> > DefineMapOwning;
+typedef std::map< std::string, Define > DefineMap;
/** @brief Class that manages the defines available while
* preprocessing files.
@@ -130,39 +130,44 @@ class DefineManager
{
m_includedFiles.insert(fileName);
}
- void store(const DefineMapOwning &fromMap)
+ void store(const DefineMap &fromMap)
{
for (auto &kv : fromMap)
{
- m_defines.emplace(kv.first,std::make_unique<Define>(*kv.second.get()));
+ m_defines.emplace(kv.first,kv.second);
}
+ //printf(" m_defines.size()=%zu\n",m_defines.size());
+ m_stored=true;
}
- void retrieve(DefineMapOwning &toMap)
+ void retrieve(DefineMap &toMap)
{
StringSet includeStack;
retrieveRec(toMap,includeStack);
}
- void retrieveRec(DefineMapOwning &toMap,StringSet &includeStack)
+ void retrieveRec(DefineMap &toMap,StringSet &includeStack)
{
+ //printf(" retrieveRec #includedFiles=%zu\n",m_includedFiles.size());
for (auto incFile : m_includedFiles)
{
DefinesPerFile *dpf = m_parent->find(incFile);
if (dpf && includeStack.find(incFile)==includeStack.end())
{
- //printf(" processing include %s\n",incFile.data());
includeStack.insert(incFile);
dpf->retrieveRec(toMap,includeStack);
+ //printf(" retrieveRec: processing include %s: #toMap=%zu\n",incFile.data(),toMap.size());
}
}
for (auto &kv : m_defines)
{
- toMap.emplace(kv.first,std::make_unique<Define>(*kv.second.get()));
+ toMap.emplace(kv.first,kv.second);
}
}
+ bool stored() const { return m_stored; }
private:
DefineManager *m_parent;
- DefineMapOwning m_defines;
+ DefineMap m_defines;
StringSet m_includedFiles;
+ bool m_stored = false;
};
friend class DefinesPerFile;
@@ -170,16 +175,19 @@ class DefineManager
void addInclude(std::string fromFileName,std::string toFileName)
{
+ //printf("DefineManager::addInclude('%s'->'%s')\n",fromFileName.c_str(),toFileName.c_str());
auto it = m_fileMap.find(fromFileName);
- if (it!=m_fileMap.end())
+ if (it==m_fileMap.end())
{
- auto &dpf = it->second;
- dpf->addInclude(toFileName);
+ it = m_fileMap.emplace(fromFileName,std::make_unique<DefinesPerFile>(this)).first;
}
+ auto &dpf = it->second;
+ dpf->addInclude(toFileName);
}
- void store(std::string fileName,const DefineMapOwning &fromMap)
+ void store(std::string fileName,const DefineMap &fromMap)
{
+ //printf("DefineManager::store(%s,#=%zu)\n",fileName.c_str(),fromMap.size());
auto it = m_fileMap.find(fileName);
if (it==m_fileMap.end())
{
@@ -188,7 +196,7 @@ class DefineManager
it->second->store(fromMap);
}
- void retrieve(std::string fileName,DefineMapOwning &toMap)
+ void retrieve(std::string fileName,DefineMap &toMap)
{
auto it = m_fileMap.find(fileName);
if (it!=m_fileMap.end())
@@ -196,11 +204,17 @@ class DefineManager
auto &dpf = it->second;
dpf->retrieve(toMap);
}
+ //printf("DefineManager::retrieve(%s,#=%zu)\n",fileName.c_str(),toMap.size());
}
bool alreadyProcessed(std::string fileName) const
{
- return m_fileMap.find(fileName)!=m_fileMap.end();
+ auto it = m_fileMap.find(fileName);
+ if (it!=m_fileMap.end())
+ {
+ return it->second->stored();
+ }
+ return false;
}
private:
@@ -277,6 +291,7 @@ struct preYY_state
yy_size_t fenceSize = 0;
bool ccomment = false;
QCString delimiter;
+ bool isSpecialComment = false;
StringVector pathList;
IntMap argMap;
BoolStack levelGuard;
@@ -285,7 +300,8 @@ struct preYY_state
std::unordered_map<std::string,Define*> expandedDict;
StringUnorderedSet expanded;
ConstExpressionParser constExpParser;
- DefineMapOwning contextDefines;
+ DefineMap contextDefines; // macros imported from other files
+ DefineMap localDefines; // macros defined in this file
DefineList macroDefinitions;
LinkedMap<PreIncludeInfo> includeRelations;
};
@@ -1131,7 +1147,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
}
<SkipCComment>^({B}*"*"+)?{B}{0,3}"~~~"[~]* {
bool markdownSupport = Config_getBool(MARKDOWN_SUPPORT);
- if (!markdownSupport)
+ if (!markdownSupport || !yyextra->isSpecialComment)
{
REJECT;
}
@@ -1144,7 +1160,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
}
<SkipCComment>^({B}*"*"+)?{B}{0,3}"```"[`]* {
bool markdownSupport = Config_getBool(MARKDOWN_SUPPORT);
- if (!markdownSupport)
+ if (!markdownSupport || !yyextra->isSpecialComment)
{
REJECT;
}
@@ -1543,7 +1559,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
{
// now that the file is completely processed, prevent it from processing it again
g_defineManager.addInclude(yyextra->yyFileName.str(),toFileName.str());
- g_defineManager.store(toFileName.str(),yyextra->contextDefines);
+ g_defineManager.store(toFileName.str(),yyextra->localDefines);
}
else
{
@@ -1553,10 +1569,21 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
}
}
}
+ // move the local macros definitions for in this file to the translation unit context
+ for (const auto &kv : yyextra->localDefines)
+ {
+ auto pair = yyextra->contextDefines.insert(kv);
+ if (!pair.second) // define already in context -> replace with local version
+ {
+ yyextra->contextDefines.erase(pair.first);
+ yyextra->contextDefines.insert(kv);
+ }
+ }
+ yyextra->localDefines.clear();
}
}
<*>"/*"/"*/" |
-<*>"/*"[*]? {
+<*>"/*"[*!]? {
if (YY_START==SkipVerbatim || YY_START==SkipCond)
{
REJECT;
@@ -1566,11 +1593,19 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
outputArray(yyscanner,yytext,(int)yyleng);
yyextra->lastCContext=YY_START;
yyextra->commentCount=1;
- if (yyleng==3) yyextra->lastGuardName.resize(0); // reset guard in case the #define is documented!
+ if (yyleng==3)
+ {
+ yyextra->isSpecialComment = true;
+ yyextra->lastGuardName.resize(0); // reset guard in case the #define is documented!
+ }
+ else
+ {
+ yyextra->isSpecialComment = false;
+ }
BEGIN(SkipCComment);
}
}
-<*>"//"[/]? {
+<*>"//"[/!]? {
if (YY_START==SkipVerbatim || YY_START==SkipCond || getLanguageFromFileName(yyextra->yyFileName)==SrcLangExt_Fortran)
{
REJECT;
@@ -1579,7 +1614,15 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
{
outputArray(yyscanner,yytext,(int)yyleng);
yyextra->lastCPPContext=YY_START;
- if (yyleng==3) yyextra->lastGuardName.resize(0); // reset guard in case the #define is documented!
+ if (yyleng==3)
+ {
+ yyextra->isSpecialComment = true;
+ yyextra->lastGuardName.resize(0); // reset guard in case the #define is documented!
+ }
+ else
+ {
+ yyextra->isSpecialComment = false;
+ }
BEGIN(SkipCPPComment);
}
}
@@ -2676,29 +2719,29 @@ static QCString expandMacro(yyscan_t yyscanner,const QCString &name)
static void addDefine(yyscan_t yyscanner)
{
YY_EXTRA_TYPE state = preYYget_extra(yyscanner);
- std::unique_ptr<Define> def = std::make_unique<Define>();
- def->name = state->defName;
- def->definition = state->defText.stripWhiteSpace();
- def->nargs = state->defArgs;
- def->fileName = state->yyFileName;
- def->fileDef = state->yyFileDef;
- def->lineNr = state->yyLineNr-state->yyMLines;
- def->columnNr = state->yyColNr;
- def->varArgs = state->defVarArgs;
- //printf("newDefine: %s %s file: %s\n",def->name.data(),def->definition.data(),
- // def->fileDef ? def->fileDef->name().data() : def->fileName.data());
- //printf("newDefine: '%s'->'%s'\n",def->name.data(),def->definition.data());
- if (!def->name.isEmpty() &&
- Doxygen::expandAsDefinedSet.find(def->name.str())!=Doxygen::expandAsDefinedSet.end())
+ Define def;
+ def.name = state->defName;
+ def.definition = state->defText.stripWhiteSpace();
+ def.nargs = state->defArgs;
+ def.fileName = state->yyFileName;
+ def.fileDef = state->yyFileDef;
+ def.lineNr = state->yyLineNr-state->yyMLines;
+ def.columnNr = state->yyColNr;
+ def.varArgs = state->defVarArgs;
+ //printf("newDefine: %s %s file: %s\n",def.name.data(),def.definition.data(),
+ // def.fileDef ? def.fileDef->name().data() : def.fileName.data());
+ //printf("newDefine: '%s'->'%s'\n",def.name.data(),def.definition.data());
+ if (!def.name.isEmpty() &&
+ Doxygen::expandAsDefinedSet.find(def.name.str())!=Doxygen::expandAsDefinedSet.end())
{
- def->isPredefined=TRUE;
+ def.isPredefined=TRUE;
}
- auto it = state->contextDefines.find(def->name.str());
- if (it!=state->contextDefines.end()) // redefine
+ auto it = state->localDefines.find(def.name.str());
+ if (it!=state->localDefines.end()) // redefine
{
- state->contextDefines.erase(it);
+ state->localDefines.erase(it);
}
- state->contextDefines.insert(std::make_pair(toStdString(def->name),std::move(def)));
+ state->localDefines.insert(std::make_pair(def.name.str(),def));
}
static void addMacroDefinition(yyscan_t yyscanner)
@@ -2707,13 +2750,13 @@ static void addMacroDefinition(yyscan_t yyscanner)
if (state->skip) return; // do not add this define as it is inside a
// conditional section (cond command) that is disabled.
- auto define = std::make_unique<Define>();
- define->fileName = state->yyFileName;
- define->lineNr = state->yyLineNr - state->yyMLines;
- define->columnNr = state->yyColNr;
- define->name = state->defName;
- define->args = state->defArgsStr;
- define->fileDef = state->inputFileDef;
+ Define define;
+ define.fileName = state->yyFileName;
+ define.lineNr = state->yyLineNr - state->yyMLines;
+ define.columnNr = state->yyColNr;
+ define.name = state->defName;
+ define.args = state->defArgsStr;
+ define.fileDef = state->inputFileDef;
QCString litText = state->defLitText;
int l=litText.find('\n');
@@ -2734,14 +2777,14 @@ static void addMacroDefinition(yyscan_t yyscanner)
QCString litTextStripped = state->defLitText.stripWhiteSpace();
if (litTextStripped.contains('\n')>=1)
{
- define->definition = litText;
+ define.definition = litText;
}
else
{
- define->definition = litTextStripped;
+ define.definition = litTextStripped;
}
{
- state->macroDefinitions.push_back(std::move(define));
+ state->macroDefinitions.push_back(define);
}
}
@@ -2837,6 +2880,11 @@ static void readIncludeFile(yyscan_t yyscanner,const QCString &inc)
//printf("calling findFile(%s)\n",incFileName.data());
if ((fs=findFile(yyscanner,incFileName,localInclude,alreadyProcessed))) // see if the include file can be found
{
+ {
+ std::lock_guard<std::mutex> lock(g_globalDefineMutex);
+ g_defineManager.addInclude(oldFileName.str(),absIncFileName.str());
+ }
+
//printf("Found include file!\n");
if (Debug::isFlagSet(Debug::Preprocessor))
{
@@ -2844,7 +2892,7 @@ static void readIncludeFile(yyscan_t yyscanner,const QCString &inc)
{
Debug::print(Debug::Preprocessor,0," ");
}
- //msg("#include %s: parsing...\n",incFileName.data());
+ Debug::print(Debug::Preprocessor,0,"#include %s: parsing...\n",incFileName.data());
}
if (state->includeStack.empty() && oldFileDef)
@@ -2893,6 +2941,7 @@ static void readIncludeFile(yyscan_t yyscanner,const QCString &inc)
// in the local context
{
std::lock_guard<std::mutex> lock(g_globalDefineMutex);
+ g_defineManager.addInclude(state->yyFileName.str(),absIncFileName.str());
g_defineManager.retrieve(absIncFileName.str(),state->contextDefines);
}
@@ -2915,6 +2964,10 @@ static void readIncludeFile(yyscan_t yyscanner,const QCString &inc)
if (Debug::isFlagSet(Debug::Preprocessor))
{
+ for (i=0;i<state->includeStack.size();i++)
+ {
+ Debug::print(Debug::Preprocessor,0," ");
+ }
if (alreadyProcessed)
{
Debug::print(Debug::Preprocessor,0,"#include %s: already processed! skipping...\n",qPrint(incFileName));
@@ -2929,7 +2982,6 @@ static void readIncludeFile(yyscan_t yyscanner,const QCString &inc)
{
warn(state->yyFileName,state->yyLineNr,"include file %s not found, perhaps you forgot to add its directory to INCLUDE_PATH?",incFileName.data());
}
-
}
}
}
@@ -3084,17 +3136,30 @@ static void unputChar(yyscan_t yyscanner,const QCString &expr,QCString *rest,uin
static Define *isDefined(yyscan_t yyscanner,const char *name)
{
YY_EXTRA_TYPE state = preYYget_extra(yyscanner);
- Define *d=0;
- auto it = state->contextDefines.find(name);
- if (it!=state->contextDefines.end())
+
+ bool undef = false;
+ auto findDefine = [&undef,&name](DefineMap &map)
{
- d = it->second.get();
- if (d->undef)
+ Define *d=0;
+ auto it = map.find(name);
+ if (it!=map.end())
{
- d=0;
+ d = &it->second;
+ if (d->undef)
+ {
+ undef=true;
+ d=0;
+ }
}
+ return d;
+ };
+
+ Define *def = findDefine(state->localDefines);
+ if (def==0 && !undef)
+ {
+ def = findDefine(state->contextDefines);
}
- return d;
+ return def;
}
static void initPredefined(yyscan_t yyscanner,const char *fileName)
@@ -3168,15 +3233,15 @@ static void initPredefined(yyscan_t yyscanner,const char *fileName)
QCString dname = ds.left(i_obrace);
if (!dname.isEmpty())
{
- std::unique_ptr<Define> def = std::make_unique<Define>();
- def->name = dname;
- def->definition = definition;
- def->nargs = count;
- def->isPredefined = TRUE;
- def->nonRecursive = nonRecursive;
- def->fileDef = state->yyFileDef;
- def->fileName = fileName;
- state->contextDefines.insert(std::make_pair(toStdString(def->name),std::move(def)));
+ Define def;
+ def.name = dname;
+ def.definition = definition;
+ def.nargs = count;
+ def.isPredefined = TRUE;
+ def.nonRecursive = nonRecursive;
+ def.fileDef = state->yyFileDef;
+ def.fileName = fileName;
+ state->contextDefines.insert(std::make_pair(def.name.str(),def));
//printf("#define '%s' '%s' #nargs=%d\n",
// def->name.data(),def->definition.data(),def->nargs);
@@ -3189,26 +3254,26 @@ static void initPredefined(yyscan_t yyscanner,const char *fileName)
) // predefined non-function macro definition
{
//printf("predefined normal macro '%s'\n",defStr);
- std::unique_ptr<Define> def = std::make_unique<Define>();
+ Define def;
if (i_equals==-1) // simple define without argument
{
- def->name = ds;
- def->definition = "1"; // substitute occurrences by 1 (true)
+ def.name = ds;
+ def.definition = "1"; // substitute occurrences by 1 (true)
}
else // simple define with argument
{
int ine=i_equals - (nonRecursive ? 1 : 0);
- def->name = ds.left(ine);
- def->definition = ds.right(ds.length()-i_equals-1);
+ def.name = ds.left(ine);
+ def.definition = ds.right(ds.length()-i_equals-1);
}
- if (!def->name.isEmpty())
+ if (!def.name.isEmpty())
{
- def->nargs = -1;
- def->isPredefined = TRUE;
- def->nonRecursive = nonRecursive;
- def->fileDef = state->yyFileDef;
- def->fileName = fileName;
- state->contextDefines.insert(std::make_pair(toStdString(def->name),std::move(def)));
+ def.nargs = -1;
+ def.isPredefined = TRUE;
+ def.nonRecursive = nonRecursive;
+ def.fileDef = state->yyFileDef;
+ def.fileName = fileName;
+ state->contextDefines.insert(std::make_pair(def.name.str(),def));
}
}
}
@@ -3322,7 +3387,11 @@ void Preprocessor::processFile(const char *fileName,BufStr &input,BufStr &output
Debug::print(Debug::Preprocessor,0,"---------\n");
for (auto &kv : yyextra->contextDefines)
{
- Debug::print(Debug::Preprocessor,0,"%s ",qPrint(kv.second->name));
+ Debug::print(Debug::Preprocessor,0,"%s ",qPrint(kv.second.name));
+ }
+ for (auto &kv : yyextra->localDefines)
+ {
+ Debug::print(Debug::Preprocessor,0,"%s ",qPrint(kv.second.name));
}
Debug::print(Debug::Preprocessor,0,"\n---------\n");
}