diff options
-rw-r--r-- | Source/cmCPluginAPI.cxx | 3 | ||||
-rw-r--r-- | Source/cmForEachCommand.cxx | 2 | ||||
-rw-r--r-- | Source/cmListFileCache.cxx | 48 | ||||
-rw-r--r-- | Source/cmListFileCache.h | 19 | ||||
-rw-r--r-- | Source/cmMacroCommand.cxx | 16 | ||||
-rw-r--r-- | Source/cmMakefile.cxx | 20 | ||||
-rw-r--r-- | Source/cmMakefile.h | 4 |
7 files changed, 92 insertions, 20 deletions
diff --git a/Source/cmCPluginAPI.cxx b/Source/cmCPluginAPI.cxx index 3ca886a..41c9337 100644 --- a/Source/cmCPluginAPI.cxx +++ b/Source/cmCPluginAPI.cxx @@ -356,7 +356,8 @@ int cmExecuteCommand(void *arg, const char *name, for(int i = 0; i < numArgs; ++i) { // Assume all arguments are quoted. - lff.m_Arguments.push_back(cmListFileArgument(args[i], true)); + lff.m_Arguments.push_back(cmListFileArgument(args[i], true, + "[CMake-Plugin]", 0)); } return mf->ExecuteCommand(lff); } diff --git a/Source/cmForEachCommand.cxx b/Source/cmForEachCommand.cxx index f8bda28..06f69ac 100644 --- a/Source/cmForEachCommand.cxx +++ b/Source/cmForEachCommand.cxx @@ -58,6 +58,8 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf) cmSystemTools::ReplaceString(tmps, variable.c_str(), j->c_str()); arg.Value = tmps; arg.Quoted = k->Quoted; + arg.FilePath = k->FilePath; + arg.Line = k->Line; newLFF.m_Arguments.push_back(arg); } mf.ExecuteCommand(newLFF); diff --git a/Source/cmListFileCache.cxx b/Source/cmListFileCache.cxx index 0638b38..e56b19b 100644 --- a/Source/cmListFileCache.cxx +++ b/Source/cmListFileCache.cxx @@ -90,6 +90,9 @@ bool cmListFileCache::CacheFile(const char* path, bool requireProjectCommand) return false; } + // Get a pointer to a persistent copy of the name. + const char* filename = this->GetUniqueStringPointer(path); + // Create the scanner. cmListFileLexer* lexer = cmListFileLexer_New(); if(!lexer) @@ -99,17 +102,17 @@ bool cmListFileCache::CacheFile(const char* path, bool requireProjectCommand) } // Open the file. - if(!cmListFileLexer_SetFileName(lexer, path)) + if(!cmListFileLexer_SetFileName(lexer, filename)) { cmListFileLexer_Delete(lexer); - cmSystemTools::Error("cmListFileCache: error can not open file ", path); + cmSystemTools::Error("cmListFileCache: error can not open file ", filename); return false; } // Use a simple recursive-descent parser to process the token // stream. cmListFile inFile; - inFile.m_ModifiedTime = cmSystemTools::ModifiedTime(path); + inFile.m_ModifiedTime = cmSystemTools::ModifiedTime(filename); bool parseError = false; bool haveNewline = true; cmListFileLexer_Token* token; @@ -126,9 +129,9 @@ bool cmListFileCache::CacheFile(const char* path, bool requireProjectCommand) haveNewline = false; cmListFileFunction inFunction; inFunction.m_Name = token->text; - inFunction.m_FilePath = path; + inFunction.m_FilePath = filename; inFunction.m_Line = token->line; - if(cmListFileCacheParseFunction(lexer, inFunction, path)) + if(cmListFileCacheParseFunction(lexer, inFunction, filename)) { inFile.m_Functions.push_back(inFunction); } @@ -141,7 +144,7 @@ bool cmListFileCache::CacheFile(const char* path, bool requireProjectCommand) { cmOStringStream error; error << "Error in cmake code at\n" - << path << ":" << token->line << ":\n" + << filename << ":" << token->line << ":\n" << "Parse error. Expected a newline, got \"" << token->text << "\"."; cmSystemTools::Error(error.str().c_str()); @@ -152,7 +155,7 @@ bool cmListFileCache::CacheFile(const char* path, bool requireProjectCommand) { cmOStringStream error; error << "Error in cmake code at\n" - << path << ":" << token->line << ":\n" + << filename << ":" << token->line << ":\n" << "Parse error. Expected a command name, got \"" << token->text << "\"."; cmSystemTools::Error(error.str().c_str()); @@ -185,12 +188,12 @@ bool cmListFileCache::CacheFile(const char* path, bool requireProjectCommand) { cmListFileFunction project; project.m_Name = "PROJECT"; - cmListFileArgument prj("Project", false); + cmListFileArgument prj("Project", false, filename, 0); project.m_Arguments.push_back(prj); inFile.m_Functions.insert(inFile.m_Functions.begin(),project); } } - m_ListFileCache[path] = inFile; + m_ListFileCache[filename] = inFile; return true; } @@ -241,13 +244,13 @@ bool cmListFileCacheParseFunction(cmListFileLexer* lexer, token->type == cmListFileLexer_Token_ArgumentUnquoted) { cmListFileArgument a(cmSystemTools::RemoveEscapes(token->text), - false); + false, filename, token->line); function.m_Arguments.push_back(a); } else if(token->type == cmListFileLexer_Token_ArgumentQuoted) { cmListFileArgument a(cmSystemTools::RemoveEscapes(token->text), - true); + true, filename, token->line); function.m_Arguments.push_back(a); } else if(token->type != cmListFileLexer_Token_Newline) @@ -272,3 +275,26 @@ bool cmListFileCacheParseFunction(cmListFileLexer* lexer, return false; } + +//---------------------------------------------------------------------------- +const char* cmListFileCache::GetUniqueStringPointer(const char* name) +{ + UniqueStrings::iterator i = m_UniqueStrings.find(name); + if(i == m_UniqueStrings.end()) + { + char* str = new char[strlen(name)+1]; + strcpy(str, name); + i = m_UniqueStrings.insert(UniqueStrings::value_type(name, str)).first; + } + return i->second; +} + +//---------------------------------------------------------------------------- +cmListFileCache::~cmListFileCache() +{ + for(UniqueStrings::iterator i = m_UniqueStrings.begin(); + i != m_UniqueStrings.end(); ++i) + { + delete [] i->second; + } +} diff --git a/Source/cmListFileCache.h b/Source/cmListFileCache.h index 8dc371f..17239d2 100644 --- a/Source/cmListFileCache.h +++ b/Source/cmListFileCache.h @@ -28,9 +28,12 @@ struct cmListFileArgument { - cmListFileArgument(): Value(), Quoted(false) {} - cmListFileArgument(const cmListFileArgument& r): Value(r.Value), Quoted(r.Quoted) {} - cmListFileArgument(const std::string& v, bool q): Value(v), Quoted(q) {} + cmListFileArgument(): Value(), Quoted(false), FilePath(0), Line(0) {} + cmListFileArgument(const cmListFileArgument& r): + Value(r.Value), Quoted(r.Quoted), FilePath(r.FilePath), Line(r.Line) {} + cmListFileArgument(const std::string& v, bool q, const char* file, + long line): Value(v), Quoted(q), + FilePath(file), Line(line) {} bool operator == (const cmListFileArgument& r) const { return (this->Value == r.Value) && (this->Quoted == r.Quoted); @@ -41,13 +44,15 @@ struct cmListFileArgument } std::string Value; bool Quoted; + const char* FilePath; + long Line; }; struct cmListFileFunction { std::string m_Name; std::vector<cmListFileArgument> m_Arguments; - std::string m_FilePath; + const char* m_FilePath; long m_Line; }; @@ -80,12 +85,18 @@ public: //! Flush cache file out of cache. void FlushCache(const char* path); + ~cmListFileCache(); private: // Cache the file bool CacheFile(const char* path, bool requireProjectCommand); // private data typedef std::map<cmStdString, cmListFile> ListFileMap; ListFileMap m_ListFileCache; // file name to ListFile map + + typedef std::map<cmStdString, char*> UniqueStrings; + UniqueStrings m_UniqueStrings; + const char* GetUniqueStringPointer(const char* name); + static cmListFileCache* Instance; // singelton pointer }; diff --git a/Source/cmMacroCommand.cxx b/Source/cmMacroCommand.cxx index dcf941a..9db5f16 100644 --- a/Source/cmMacroCommand.cxx +++ b/Source/cmMacroCommand.cxx @@ -173,6 +173,22 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf) arg.Value = tmps; arg.Quoted = k->Quoted; + const char* def = + mf.GetDefinition("CMAKE_MACRO_REPORT_DEFINITION_LOCATION"); + if(def && !cmSystemTools::IsOff(def)) + { + // Report the location of the argument where the macro was + // defined. + arg.FilePath = k->FilePath; + arg.Line = k->Line; + } + else + { + // Report the location of the argument where the macro was + // invoked. + arg.FilePath = lff.m_FilePath; + arg.Line = lff.m_Line; + } newLFF.m_Arguments.push_back(arg); } if(!mf.ExecuteCommand(newLFF)) diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index f6b7225..4df29b1 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -1423,7 +1423,9 @@ const char *cmMakefile::ExpandVariablesInString(std::string& source) const const char *cmMakefile::ExpandVariablesInString(std::string& source, bool escapeQuotes, - bool atOnly) const + bool atOnly, + const char* filename = 0, + long line = -1) const { // This method replaces ${VAR} and @VAR@ where VAR is looked up // with GetDefinition(), if not found in the map, nothing is expanded. @@ -1542,6 +1544,18 @@ const char *cmMakefile::ExpandVariablesInString(std::string& source, } found = true; } + else if(filename && (var == "CMAKE_CURRENT_LIST_FILE")) + { + result += filename; + found = true; + } + else if(line >= 0 && (var == "CMAKE_CURRENT_LIST_LINE")) + { + cmOStringStream ostr; + ostr << line; + result += ostr.str(); + found = true; + } } // if found add to result, if not, then it gets blanked if (!found) @@ -1696,8 +1710,8 @@ void cmMakefile::ExpandArguments( { // Expand the variables in the argument. value = i->Value; - this->ExpandVariablesInString(value); - + this->ExpandVariablesInString(value, false, false, i->FilePath, i->Line); + // If the argument is quoted, it should be one argument. // Otherwise, it may be a list of arguments. if(i->Quoted) diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index d417f74..efca41e 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -558,7 +558,9 @@ public: */ const char *ExpandVariablesInString(std::string& source) const; const char *ExpandVariablesInString(std::string& source, bool escapeQuotes, - bool atOnly = false) const; + bool atOnly = false, + const char* filename = 0, + long line = -1) const; /** * Remove any remaining variables in the string. Anything with ${var} or |