forked from qt-creator/qt-creator
CMakePM: Integrate CMake's lexer
Kept only the needed bits to parse the CMake files. Change-Id: I7c4aa0779846fcee91469a38f84d801513e3aa63 Reviewed-by: <github-actions-qt-creator@cristianadam.eu> Reviewed-by: Eike Ziller <eike.ziller@qt.io>
This commit is contained in:
@@ -7,41 +7,29 @@
|
||||
#include <sstream>
|
||||
#include <utility>
|
||||
|
||||
#ifdef _WIN32
|
||||
# include <cmsys/Encoding.hxx>
|
||||
#endif
|
||||
|
||||
#include "cmListFileLexer.h"
|
||||
#include "cmMessageType.h"
|
||||
#include "cmMessenger.h"
|
||||
#include "cmStringAlgorithms.h"
|
||||
#include "cmSystemTools.h"
|
||||
|
||||
struct cmListFileParser
|
||||
{
|
||||
cmListFileParser(cmListFile* lf, cmListFileBacktrace lfbt,
|
||||
cmMessenger* messenger);
|
||||
cmListFileParser(cmListFile* lf, std::string &error);
|
||||
~cmListFileParser();
|
||||
cmListFileParser(const cmListFileParser&) = delete;
|
||||
cmListFileParser& operator=(const cmListFileParser&) = delete;
|
||||
void IssueFileOpenError(std::string const& text) const;
|
||||
void IssueError(std::string const& text) const;
|
||||
bool ParseFile(const char* filename);
|
||||
bool ParseString(const char* str, const char* virtual_filename);
|
||||
bool ParseString(const std::string &str, const std::string &virtual_filename);
|
||||
bool Parse();
|
||||
bool ParseFunction(const char* name, long line);
|
||||
bool AddArgument(cmListFileLexer_Token* token,
|
||||
cmListFileArgument::Delimiter delim);
|
||||
cm::optional<cmListFileContext> CheckNesting() const;
|
||||
cmListFile* ListFile;
|
||||
cmListFileBacktrace Backtrace;
|
||||
cmMessenger* Messenger;
|
||||
const char* FileName = nullptr;
|
||||
cmListFileLexer* Lexer;
|
||||
std::string FunctionName;
|
||||
long FunctionLine;
|
||||
long FunctionLineEnd;
|
||||
std::vector<cmListFileArgument> FunctionArguments;
|
||||
std::string &Error;
|
||||
enum
|
||||
{
|
||||
SeparationOkay,
|
||||
@@ -50,12 +38,10 @@ struct cmListFileParser
|
||||
} Separation;
|
||||
};
|
||||
|
||||
cmListFileParser::cmListFileParser(cmListFile* lf, cmListFileBacktrace lfbt,
|
||||
cmMessenger* messenger)
|
||||
: ListFile(lf)
|
||||
, Backtrace(std::move(lfbt))
|
||||
, Messenger(messenger)
|
||||
, Lexer(cmListFileLexer_New())
|
||||
cmListFileParser::cmListFileParser(cmListFile *lf, std::string &error)
|
||||
: ListFile(lf)
|
||||
, Lexer(cmListFileLexer_New())
|
||||
, Error(error)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -64,65 +50,19 @@ cmListFileParser::~cmListFileParser()
|
||||
cmListFileLexer_Delete(this->Lexer);
|
||||
}
|
||||
|
||||
void cmListFileParser::IssueFileOpenError(const std::string& text) const
|
||||
{
|
||||
this->Messenger->IssueMessage(MessageType::FATAL_ERROR, text,
|
||||
this->Backtrace);
|
||||
}
|
||||
|
||||
void cmListFileParser::IssueError(const std::string& text) const
|
||||
{
|
||||
cmListFileContext lfc;
|
||||
lfc.FilePath = this->FileName;
|
||||
lfc.Line = cmListFileLexer_GetCurrentLine(this->Lexer);
|
||||
cmListFileBacktrace lfbt = this->Backtrace;
|
||||
lfbt = lfbt.Push(lfc);
|
||||
this->Messenger->IssueMessage(MessageType::FATAL_ERROR, text, lfbt);
|
||||
cmSystemTools::SetFatalErrorOccurred();
|
||||
Error += text;
|
||||
Error += "\n";
|
||||
}
|
||||
|
||||
bool cmListFileParser::ParseFile(const char* filename)
|
||||
bool cmListFileParser::ParseString(const std::string &str,
|
||||
const std::string &virtual_filename)
|
||||
{
|
||||
this->FileName = filename;
|
||||
this->FileName = virtual_filename.c_str();
|
||||
|
||||
#ifdef _WIN32
|
||||
std::string expandedFileName = cmsys::Encoding::ToNarrow(
|
||||
cmSystemTools::ConvertToWindowsExtendedPath(filename));
|
||||
filename = expandedFileName.c_str();
|
||||
#endif
|
||||
|
||||
// Open the file.
|
||||
cmListFileLexer_BOM bom;
|
||||
if (!cmListFileLexer_SetFileName(this->Lexer, filename, &bom)) {
|
||||
this->IssueFileOpenError("cmListFileCache: error can not open file.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (bom == cmListFileLexer_BOM_Broken) {
|
||||
cmListFileLexer_SetFileName(this->Lexer, nullptr, nullptr);
|
||||
this->IssueFileOpenError("Error while reading Byte-Order-Mark. "
|
||||
"File not seekable?");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Verify the Byte-Order-Mark, if any.
|
||||
if (bom != cmListFileLexer_BOM_None && bom != cmListFileLexer_BOM_UTF8) {
|
||||
cmListFileLexer_SetFileName(this->Lexer, nullptr, nullptr);
|
||||
this->IssueFileOpenError(
|
||||
"File starts with a Byte-Order-Mark that is not UTF-8.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return this->Parse();
|
||||
}
|
||||
|
||||
bool cmListFileParser::ParseString(const char* str,
|
||||
const char* virtual_filename)
|
||||
{
|
||||
this->FileName = virtual_filename;
|
||||
|
||||
if (!cmListFileLexer_SetString(this->Lexer, str)) {
|
||||
this->IssueFileOpenError("cmListFileCache: cannot allocate buffer.");
|
||||
if (!cmListFileLexer_SetString(this->Lexer, str.c_str(), (int)str.size())) {
|
||||
this->IssueError("cmListFileCache: cannot allocate buffer.");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -138,7 +78,8 @@ bool cmListFileParser::Parse()
|
||||
if (token->type == cmListFileLexer_Token_Space) {
|
||||
} else if (token->type == cmListFileLexer_Token_Newline) {
|
||||
haveNewline = true;
|
||||
} else if (token->type == cmListFileLexer_Token_CommentBracket) {
|
||||
} else if (token->type == cmListFileLexer_Token_CommentBracket
|
||||
|| token->type == cmListFileLexer_Token_CommentLine) {
|
||||
haveNewline = false;
|
||||
} else if (token->type == cmListFileLexer_Token_Identifier) {
|
||||
if (haveNewline) {
|
||||
@@ -168,45 +109,15 @@ bool cmListFileParser::Parse()
|
||||
}
|
||||
}
|
||||
|
||||
// Check if all functions are nested properly.
|
||||
if (auto badNesting = this->CheckNesting()) {
|
||||
this->Messenger->IssueMessage(
|
||||
MessageType::FATAL_ERROR,
|
||||
"Flow control statements are not properly nested.",
|
||||
this->Backtrace.Push(*badNesting));
|
||||
cmSystemTools::SetFatalErrorOccurred();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cmListFile::ParseFile(const char* filename, cmMessenger* messenger,
|
||||
cmListFileBacktrace const& lfbt)
|
||||
{
|
||||
if (!cmSystemTools::FileExists(filename) ||
|
||||
cmSystemTools::FileIsDirectory(filename)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool parseError = false;
|
||||
|
||||
{
|
||||
cmListFileParser parser(this, lfbt, messenger);
|
||||
parseError = !parser.ParseFile(filename);
|
||||
}
|
||||
|
||||
return !parseError;
|
||||
}
|
||||
|
||||
bool cmListFile::ParseString(const char* str, const char* virtual_filename,
|
||||
cmMessenger* messenger,
|
||||
const cmListFileBacktrace& lfbt)
|
||||
bool cmListFile::ParseString(const std::string &str, const std::string& virtual_filename, std::string &error)
|
||||
{
|
||||
bool parseError = false;
|
||||
|
||||
{
|
||||
cmListFileParser parser(this, lfbt, messenger);
|
||||
cmListFileParser parser(this, error);
|
||||
parseError = !parser.ParseString(str, virtual_filename);
|
||||
}
|
||||
|
||||
@@ -279,6 +190,11 @@ bool cmListFileParser::ParseFunction(const char* name, long line)
|
||||
return false;
|
||||
}
|
||||
this->Separation = SeparationWarning;
|
||||
} else if (token->type == cmListFileLexer_Token_CommentLine) {
|
||||
if (!this->AddArgument(token, cmListFileArgument::Comment)) {
|
||||
return false;
|
||||
}
|
||||
this->Separation = SeparationWarning;
|
||||
} else if (token->type == cmListFileLexer_Token_ArgumentBracket) {
|
||||
if (!this->AddArgument(token, cmListFileArgument::Bracket)) {
|
||||
return false;
|
||||
@@ -299,210 +215,30 @@ bool cmListFileParser::ParseFunction(const char* name, long line)
|
||||
}
|
||||
|
||||
std::ostringstream error;
|
||||
cmListFileContext lfc;
|
||||
lfc.FilePath = this->FileName;
|
||||
lfc.Line = line;
|
||||
cmListFileBacktrace lfbt = this->Backtrace;
|
||||
lfbt = lfbt.Push(lfc);
|
||||
error << "Parse error. Function missing ending \")\". "
|
||||
<< "End of file reached.";
|
||||
this->Messenger->IssueMessage(MessageType::FATAL_ERROR, error.str(), lfbt);
|
||||
IssueError(error.str());
|
||||
return false;
|
||||
}
|
||||
|
||||
bool cmListFileParser::AddArgument(cmListFileLexer_Token* token,
|
||||
cmListFileArgument::Delimiter delim)
|
||||
{
|
||||
this->FunctionArguments.emplace_back(token->text, delim, token->line);
|
||||
this->FunctionArguments.emplace_back(token->text, delim, token->line, token->column);
|
||||
if (this->Separation == SeparationOkay) {
|
||||
return true;
|
||||
}
|
||||
bool isError = (this->Separation == SeparationError ||
|
||||
delim == cmListFileArgument::Bracket);
|
||||
std::ostringstream m;
|
||||
cmListFileContext lfc;
|
||||
lfc.FilePath = this->FileName;
|
||||
lfc.Line = token->line;
|
||||
cmListFileBacktrace lfbt = this->Backtrace;
|
||||
lfbt = lfbt.Push(lfc);
|
||||
|
||||
m << "Syntax " << (isError ? "Error" : "Warning") << " in cmake code at "
|
||||
<< "column " << token->column << "\n"
|
||||
<< "Argument not separated from preceding token by whitespace.";
|
||||
/* clang-format on */
|
||||
if (isError) {
|
||||
this->Messenger->IssueMessage(MessageType::FATAL_ERROR, m.str(), lfbt);
|
||||
IssueError(m.str());
|
||||
return false;
|
||||
}
|
||||
this->Messenger->IssueMessage(MessageType::AUTHOR_WARNING, m.str(), lfbt);
|
||||
return true;
|
||||
}
|
||||
|
||||
namespace {
|
||||
enum class NestingStateEnum
|
||||
{
|
||||
If,
|
||||
Else,
|
||||
While,
|
||||
Foreach,
|
||||
Function,
|
||||
Macro,
|
||||
Block
|
||||
};
|
||||
|
||||
struct NestingState
|
||||
{
|
||||
NestingStateEnum State;
|
||||
cmListFileContext Context;
|
||||
};
|
||||
|
||||
bool TopIs(std::vector<NestingState>& stack, NestingStateEnum state)
|
||||
{
|
||||
return !stack.empty() && stack.back().State == state;
|
||||
}
|
||||
}
|
||||
|
||||
cm::optional<cmListFileContext> cmListFileParser::CheckNesting() const
|
||||
{
|
||||
std::vector<NestingState> stack;
|
||||
|
||||
for (auto const& func : this->ListFile->Functions) {
|
||||
auto const& name = func.LowerCaseName();
|
||||
if (name == "if") {
|
||||
stack.push_back({
|
||||
NestingStateEnum::If,
|
||||
cmListFileContext::FromListFileFunction(func, this->FileName),
|
||||
});
|
||||
} else if (name == "elseif") {
|
||||
if (!TopIs(stack, NestingStateEnum::If)) {
|
||||
return cmListFileContext::FromListFileFunction(func, this->FileName);
|
||||
}
|
||||
stack.back() = {
|
||||
NestingStateEnum::If,
|
||||
cmListFileContext::FromListFileFunction(func, this->FileName),
|
||||
};
|
||||
} else if (name == "else") {
|
||||
if (!TopIs(stack, NestingStateEnum::If)) {
|
||||
return cmListFileContext::FromListFileFunction(func, this->FileName);
|
||||
}
|
||||
stack.back() = {
|
||||
NestingStateEnum::Else,
|
||||
cmListFileContext::FromListFileFunction(func, this->FileName),
|
||||
};
|
||||
} else if (name == "endif") {
|
||||
if (!TopIs(stack, NestingStateEnum::If) &&
|
||||
!TopIs(stack, NestingStateEnum::Else)) {
|
||||
return cmListFileContext::FromListFileFunction(func, this->FileName);
|
||||
}
|
||||
stack.pop_back();
|
||||
} else if (name == "while") {
|
||||
stack.push_back({
|
||||
NestingStateEnum::While,
|
||||
cmListFileContext::FromListFileFunction(func, this->FileName),
|
||||
});
|
||||
} else if (name == "endwhile") {
|
||||
if (!TopIs(stack, NestingStateEnum::While)) {
|
||||
return cmListFileContext::FromListFileFunction(func, this->FileName);
|
||||
}
|
||||
stack.pop_back();
|
||||
} else if (name == "foreach") {
|
||||
stack.push_back({
|
||||
NestingStateEnum::Foreach,
|
||||
cmListFileContext::FromListFileFunction(func, this->FileName),
|
||||
});
|
||||
} else if (name == "endforeach") {
|
||||
if (!TopIs(stack, NestingStateEnum::Foreach)) {
|
||||
return cmListFileContext::FromListFileFunction(func, this->FileName);
|
||||
}
|
||||
stack.pop_back();
|
||||
} else if (name == "function") {
|
||||
stack.push_back({
|
||||
NestingStateEnum::Function,
|
||||
cmListFileContext::FromListFileFunction(func, this->FileName),
|
||||
});
|
||||
} else if (name == "endfunction") {
|
||||
if (!TopIs(stack, NestingStateEnum::Function)) {
|
||||
return cmListFileContext::FromListFileFunction(func, this->FileName);
|
||||
}
|
||||
stack.pop_back();
|
||||
} else if (name == "macro") {
|
||||
stack.push_back({
|
||||
NestingStateEnum::Macro,
|
||||
cmListFileContext::FromListFileFunction(func, this->FileName),
|
||||
});
|
||||
} else if (name == "endmacro") {
|
||||
if (!TopIs(stack, NestingStateEnum::Macro)) {
|
||||
return cmListFileContext::FromListFileFunction(func, this->FileName);
|
||||
}
|
||||
stack.pop_back();
|
||||
} else if (name == "block") {
|
||||
stack.push_back({
|
||||
NestingStateEnum::Block,
|
||||
cmListFileContext::FromListFileFunction(func, this->FileName),
|
||||
});
|
||||
} else if (name == "endblock") {
|
||||
if (!TopIs(stack, NestingStateEnum::Block)) {
|
||||
return cmListFileContext::FromListFileFunction(func, this->FileName);
|
||||
}
|
||||
stack.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
if (!stack.empty()) {
|
||||
return stack.back().Context;
|
||||
}
|
||||
|
||||
return cm::nullopt;
|
||||
}
|
||||
|
||||
#include "cmConstStack.tcc"
|
||||
template class cmConstStack<cmListFileContext, cmListFileBacktrace>;
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, cmListFileContext const& lfc)
|
||||
{
|
||||
os << lfc.FilePath;
|
||||
if (lfc.Line > 0) {
|
||||
os << ":" << lfc.Line;
|
||||
if (!lfc.Name.empty()) {
|
||||
os << " (" << lfc.Name << ")";
|
||||
}
|
||||
} else if (lfc.Line == cmListFileContext::DeferPlaceholderLine) {
|
||||
os << ":DEFERRED";
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
bool operator<(const cmListFileContext& lhs, const cmListFileContext& rhs)
|
||||
{
|
||||
if (lhs.Line != rhs.Line) {
|
||||
return lhs.Line < rhs.Line;
|
||||
}
|
||||
return lhs.FilePath < rhs.FilePath;
|
||||
}
|
||||
|
||||
bool operator==(const cmListFileContext& lhs, const cmListFileContext& rhs)
|
||||
{
|
||||
return lhs.Line == rhs.Line && lhs.FilePath == rhs.FilePath;
|
||||
}
|
||||
|
||||
bool operator!=(const cmListFileContext& lhs, const cmListFileContext& rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, BT<std::string> const& s)
|
||||
{
|
||||
return os << s.Value;
|
||||
}
|
||||
|
||||
std::vector<BT<std::string>> cmExpandListWithBacktrace(
|
||||
std::string const& list, cmListFileBacktrace const& bt, bool emptyArgs)
|
||||
{
|
||||
std::vector<BT<std::string>> result;
|
||||
std::vector<std::string> tmp = cmExpandedList(list, emptyArgs);
|
||||
result.reserve(tmp.size());
|
||||
for (std::string& i : tmp) {
|
||||
result.emplace_back(std::move(i), bt);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@@ -2,19 +2,13 @@
|
||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||
#pragma once
|
||||
|
||||
#include "cmConfigure.h" // IWYU pragma: keep
|
||||
|
||||
#include <algorithm>
|
||||
#include <iosfwd>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include <cm/optional>
|
||||
|
||||
#include "cmConstStack.h"
|
||||
#include "cmSystemTools.h"
|
||||
|
||||
/** \class cmListFileCache
|
||||
* \brief A class to cache list file contents.
|
||||
*
|
||||
@@ -22,21 +16,21 @@
|
||||
* cmake list files.
|
||||
*/
|
||||
|
||||
class cmMessenger;
|
||||
|
||||
struct cmListFileArgument
|
||||
{
|
||||
enum Delimiter
|
||||
{
|
||||
Unquoted,
|
||||
Quoted,
|
||||
Bracket
|
||||
Bracket,
|
||||
Comment
|
||||
};
|
||||
cmListFileArgument() = default;
|
||||
cmListFileArgument(std::string v, Delimiter d, long line)
|
||||
cmListFileArgument(std::string v, Delimiter d, long line, long column)
|
||||
: Value(std::move(v))
|
||||
, Delim(d)
|
||||
, Line(line)
|
||||
, Column(column)
|
||||
{
|
||||
}
|
||||
bool operator==(const cmListFileArgument& r) const
|
||||
@@ -47,6 +41,7 @@ struct cmListFileArgument
|
||||
std::string Value;
|
||||
Delimiter Delim = Unquoted;
|
||||
long Line = 0;
|
||||
long Column = 0;
|
||||
};
|
||||
|
||||
class cmListFileFunction
|
||||
@@ -83,13 +78,25 @@ private:
|
||||
Implementation(std::string name, long line, long lineEnd,
|
||||
std::vector<cmListFileArgument> args)
|
||||
: OriginalName{ std::move(name) }
|
||||
, LowerCaseName{ cmSystemTools::LowerCase(this->OriginalName) }
|
||||
, LowerCaseName{ tolower(this->OriginalName) }
|
||||
, Line{ line }
|
||||
, LineEnd{ lineEnd }
|
||||
, Arguments{ std::move(args) }
|
||||
{
|
||||
}
|
||||
|
||||
// taken from yaml-cpp
|
||||
static bool IsLower(char ch) { return 'a' <= ch && ch <= 'z'; }
|
||||
static bool IsUpper(char ch) { return 'A' <= ch && ch <= 'Z'; }
|
||||
static char ToLower(char ch) { return IsUpper(ch) ? ch + 'a' - 'A' : ch; }
|
||||
|
||||
std::string tolower(const std::string& str)
|
||||
{
|
||||
std::string s(str);
|
||||
std::transform(s.begin(), s.end(), s.begin(), ToLower);
|
||||
return s;
|
||||
}
|
||||
|
||||
std::string OriginalName;
|
||||
std::string LowerCaseName;
|
||||
long Line = 0;
|
||||
@@ -100,147 +107,9 @@ private:
|
||||
std::shared_ptr<Implementation const> Impl;
|
||||
};
|
||||
|
||||
class cmListFileContext
|
||||
{
|
||||
public:
|
||||
std::string Name;
|
||||
std::string FilePath;
|
||||
long Line = 0;
|
||||
static long const DeferPlaceholderLine = -1;
|
||||
cm::optional<std::string> DeferId;
|
||||
|
||||
cmListFileContext() = default;
|
||||
// This move constructor is marked `noexcept` yet `clang-tidy` 14 reports it
|
||||
// as being able to throw an exception. Suppress the warning as there doesn't
|
||||
// seem to be any way for this to happen given the member types.
|
||||
// NOLINTNEXTLINE(bugprone-exception-escape)
|
||||
cmListFileContext(cmListFileContext&& /*other*/) noexcept = default;
|
||||
cmListFileContext(const cmListFileContext& /*other*/) = default;
|
||||
cmListFileContext& operator=(const cmListFileContext& /*other*/) = default;
|
||||
#if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
|
||||
cmListFileContext& operator=(cmListFileContext&& /*other*/) noexcept =
|
||||
default;
|
||||
#else
|
||||
// The move assignment operators for several STL classes did not become
|
||||
// noexcept until C++17, which causes some tools to warn about this move
|
||||
// assignment operator throwing an exception when it shouldn't.
|
||||
cmListFileContext& operator=(cmListFileContext&& /*other*/) noexcept =
|
||||
delete;
|
||||
#endif
|
||||
|
||||
cmListFileContext(std::string name, std::string filePath, long line)
|
||||
: Name(std::move(name))
|
||||
, FilePath(std::move(filePath))
|
||||
, Line(line)
|
||||
{
|
||||
}
|
||||
|
||||
static cmListFileContext FromListFilePath(std::string const& filePath)
|
||||
{
|
||||
// We are entering a file-level scope but have not yet reached
|
||||
// any specific line or command invocation within it. This context
|
||||
// is useful to print when it is at the top but otherwise can be
|
||||
// skipped during call stack printing.
|
||||
cmListFileContext lfc;
|
||||
lfc.FilePath = filePath;
|
||||
return lfc;
|
||||
}
|
||||
|
||||
static cmListFileContext FromListFileFunction(
|
||||
cmListFileFunction const& lff, std::string const& fileName,
|
||||
cm::optional<std::string> deferId = {})
|
||||
{
|
||||
cmListFileContext lfc;
|
||||
lfc.FilePath = fileName;
|
||||
lfc.Line = lff.Line();
|
||||
lfc.Name = lff.OriginalName();
|
||||
lfc.DeferId = std::move(deferId);
|
||||
return lfc;
|
||||
}
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream&, cmListFileContext const&);
|
||||
bool operator<(const cmListFileContext& lhs, const cmListFileContext& rhs);
|
||||
bool operator==(cmListFileContext const& lhs, cmListFileContext const& rhs);
|
||||
bool operator!=(cmListFileContext const& lhs, cmListFileContext const& rhs);
|
||||
|
||||
// Represent a backtrace (call stack) with efficient value semantics.
|
||||
class cmListFileBacktrace
|
||||
: public cmConstStack<cmListFileContext, cmListFileBacktrace>
|
||||
{
|
||||
using cmConstStack::cmConstStack;
|
||||
friend class cmConstStack<cmListFileContext, cmListFileBacktrace>;
|
||||
};
|
||||
#ifndef cmListFileCache_cxx
|
||||
extern template class cmConstStack<cmListFileContext, cmListFileBacktrace>;
|
||||
#endif
|
||||
|
||||
// Wrap type T as a value with a backtrace. For purposes of
|
||||
// ordering and equality comparison, only the original value is
|
||||
// used. The backtrace is considered incidental.
|
||||
template <typename T>
|
||||
class BT
|
||||
{
|
||||
public:
|
||||
BT(T v = T(), cmListFileBacktrace bt = cmListFileBacktrace())
|
||||
: Value(std::move(v))
|
||||
, Backtrace(std::move(bt))
|
||||
{
|
||||
}
|
||||
T Value;
|
||||
cmListFileBacktrace Backtrace;
|
||||
friend bool operator==(BT<T> const& l, BT<T> const& r)
|
||||
{
|
||||
return l.Value == r.Value;
|
||||
}
|
||||
friend bool operator<(BT<T> const& l, BT<T> const& r)
|
||||
{
|
||||
return l.Value < r.Value;
|
||||
}
|
||||
friend bool operator==(BT<T> const& l, T const& r) { return l.Value == r; }
|
||||
friend bool operator==(T const& l, BT<T> const& r) { return l == r.Value; }
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, BT<std::string> const& s);
|
||||
|
||||
// Wrap type T as a value with potentially multiple backtraces. For purposes
|
||||
// of ordering and equality comparison, only the original value is used. The
|
||||
// backtrace is considered incidental.
|
||||
template <typename T>
|
||||
class BTs
|
||||
{
|
||||
public:
|
||||
BTs(T v = T(), cmListFileBacktrace bt = cmListFileBacktrace())
|
||||
: Value(std::move(v))
|
||||
{
|
||||
this->Backtraces.emplace_back(std::move(bt));
|
||||
}
|
||||
T Value;
|
||||
std::vector<cmListFileBacktrace> Backtraces;
|
||||
friend bool operator==(BTs<T> const& l, BTs<T> const& r)
|
||||
{
|
||||
return l.Value == r.Value;
|
||||
}
|
||||
friend bool operator<(BTs<T> const& l, BTs<T> const& r)
|
||||
{
|
||||
return l.Value < r.Value;
|
||||
}
|
||||
friend bool operator==(BTs<T> const& l, T const& r) { return l.Value == r; }
|
||||
friend bool operator==(T const& l, BTs<T> const& r) { return l == r.Value; }
|
||||
};
|
||||
|
||||
std::vector<BT<std::string>> cmExpandListWithBacktrace(
|
||||
std::string const& list,
|
||||
cmListFileBacktrace const& bt = cmListFileBacktrace(),
|
||||
bool emptyArgs = false);
|
||||
|
||||
struct cmListFile
|
||||
{
|
||||
bool ParseFile(const char* path, cmMessenger* messenger,
|
||||
cmListFileBacktrace const& lfbt);
|
||||
|
||||
bool ParseString(const char* str, const char* virtual_filename,
|
||||
cmMessenger* messenger, cmListFileBacktrace const& lfbt);
|
||||
bool ParseString(const std::string &str, const std::string &virtual_filename, std::string &error);
|
||||
|
||||
std::vector<cmListFileFunction> Functions;
|
||||
};
|
||||
|
2835
src/plugins/cmakeprojectmanager/3rdparty/cmake/cmListFileLexer.c
vendored
Normal file
2835
src/plugins/cmakeprojectmanager/3rdparty/cmake/cmListFileLexer.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@@ -21,7 +21,8 @@ typedef enum cmListFileLexer_Type_e
|
||||
cmListFileLexer_Token_CommentBracket,
|
||||
cmListFileLexer_Token_BadCharacter,
|
||||
cmListFileLexer_Token_BadBracket,
|
||||
cmListFileLexer_Token_BadString
|
||||
cmListFileLexer_Token_BadString,
|
||||
cmListFileLexer_Token_CommentLine
|
||||
} cmListFileLexer_Type;
|
||||
|
||||
/* NOLINTNEXTLINE(modernize-use-using) */
|
||||
@@ -55,7 +56,7 @@ typedef struct cmListFileLexer_s cmListFileLexer;
|
||||
cmListFileLexer* cmListFileLexer_New(void);
|
||||
int cmListFileLexer_SetFileName(cmListFileLexer*, const char*,
|
||||
cmListFileLexer_BOM* bom);
|
||||
int cmListFileLexer_SetString(cmListFileLexer*, const char*);
|
||||
int cmListFileLexer_SetString(cmListFileLexer*, const char*, int length);
|
||||
cmListFileLexer_Token* cmListFileLexer_Scan(cmListFileLexer*);
|
||||
long cmListFileLexer_GetCurrentLine(cmListFileLexer*);
|
||||
long cmListFileLexer_GetCurrentColumn(cmListFileLexer*);
|
||||
|
@@ -18,10 +18,6 @@ Modify cmListFileLexer.c:
|
||||
|
||||
/* IWYU pragma: no_forward_declare yyguts_t */
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "cmsys/Encoding.h"
|
||||
#endif
|
||||
|
||||
/* Setup the proper cmListFileLexer_yylex declaration. */
|
||||
#define YY_EXTRA_TYPE cmListFileLexer*
|
||||
#define YY_DECL int cmListFileLexer_yylex (yyscan_t yyscanner, cmListFileLexer* lexer)
|
||||
@@ -114,7 +110,10 @@ LEGACY {MAKEVAR}|{UNQUOTED}|\"({MAKEVAR}|{UNQUOTED}|[ \t[=])*\"
|
||||
}
|
||||
|
||||
<COMMENT>[^\0\n]* {
|
||||
lexer->token.type = cmListFileLexer_Token_CommentLine;
|
||||
cmListFileLexerSetToken(lexer, yytext, yyleng);
|
||||
lexer->column += yyleng;
|
||||
return 1;
|
||||
}
|
||||
|
||||
\( {
|
||||
@@ -389,7 +388,6 @@ static void cmListFileLexerDestroy(cmListFileLexer* lexer)
|
||||
lexer->file = 0;
|
||||
}
|
||||
if (lexer->string_buffer) {
|
||||
free(lexer->string_buffer);
|
||||
lexer->string_buffer = 0;
|
||||
lexer->string_left = 0;
|
||||
lexer->string_position = 0;
|
||||
@@ -458,13 +456,7 @@ int cmListFileLexer_SetFileName(cmListFileLexer* lexer, const char* name,
|
||||
int result = 1;
|
||||
cmListFileLexerDestroy(lexer);
|
||||
if (name) {
|
||||
#ifdef _WIN32
|
||||
wchar_t* wname = cmsysEncoding_DupToWide(name);
|
||||
lexer->file = _wfopen(wname, L"rb");
|
||||
free(wname);
|
||||
#else
|
||||
lexer->file = fopen(name, "rb");
|
||||
#endif
|
||||
if (lexer->file) {
|
||||
if (bom) {
|
||||
*bom = cmListFileLexer_ReadBOM(lexer->file);
|
||||
@@ -478,20 +470,14 @@ int cmListFileLexer_SetFileName(cmListFileLexer* lexer, const char* name,
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int cmListFileLexer_SetString(cmListFileLexer* lexer, const char* text)
|
||||
int cmListFileLexer_SetString(cmListFileLexer* lexer, const char* text, int length)
|
||||
{
|
||||
int result = 1;
|
||||
cmListFileLexerDestroy(lexer);
|
||||
if (text) {
|
||||
int length = (int)strlen(text);
|
||||
lexer->string_buffer = (char*)malloc(length + 1);
|
||||
if (lexer->string_buffer) {
|
||||
strcpy(lexer->string_buffer, text);
|
||||
lexer->string_position = lexer->string_buffer;
|
||||
lexer->string_left = length;
|
||||
} else {
|
||||
result = 0;
|
||||
}
|
||||
lexer->string_buffer = (char *) text;
|
||||
lexer->string_position = lexer->string_buffer;
|
||||
lexer->string_left = length;
|
||||
}
|
||||
cmListFileLexerInit(lexer);
|
||||
return result;
|
||||
@@ -555,6 +541,8 @@ const char* cmListFileLexer_GetTypeAsString(cmListFileLexer* lexer,
|
||||
return "unterminated bracket";
|
||||
case cmListFileLexer_Token_BadString:
|
||||
return "unterminated string";
|
||||
case cmListFileLexer_Token_CommentLine:
|
||||
return "line comment";
|
||||
}
|
||||
return "unknown token";
|
||||
}
|
||||
|
@@ -24,8 +24,6 @@
|
||||
# define _XOPEN_SOURCE 700
|
||||
#endif
|
||||
|
||||
#include "cmsys/Configure.h" // IWYU pragma: keep
|
||||
|
||||
/* Disable some warnings. */
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(disable : 4018)
|
||||
@@ -38,6 +36,7 @@
|
||||
# pragma warning(disable : 4309)
|
||||
# pragma warning(disable : 4706)
|
||||
# pragma warning(disable : 4786)
|
||||
# pragma warning(disable : 4996)
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) && !defined(__INTEL_COMPILER)
|
||||
@@ -80,10 +79,10 @@
|
||||
#define YY_NO_UNPUT 1
|
||||
#define ECHO
|
||||
|
||||
#include <cm3p/kwiml/int.h>
|
||||
typedef KWIML_INT_int8_t flex_int8_t;
|
||||
typedef KWIML_INT_uint8_t flex_uint8_t;
|
||||
typedef KWIML_INT_int16_t flex_int16_t;
|
||||
typedef KWIML_INT_uint16_t flex_uint16_t;
|
||||
typedef KWIML_INT_int32_t flex_int32_t;
|
||||
typedef KWIML_INT_uint32_t flex_uint32_t;
|
||||
#include <stdint.h>
|
||||
typedef int8_t flex_int8_t;
|
||||
typedef uint8_t flex_uint8_t;
|
||||
typedef int16_t flex_int16_t;
|
||||
typedef uint16_t flex_uint16_t;
|
||||
typedef int32_t flex_int32_t;
|
||||
typedef uint32_t flex_uint32_t;
|
||||
|
@@ -2,6 +2,7 @@ add_qtc_plugin(CMakeProjectManager
|
||||
PLUGIN_CLASS CMakeProjectPlugin
|
||||
DEPENDS QmlJS
|
||||
PLUGIN_DEPENDS Core CppEditor ProjectExplorer TextEditor QtSupport
|
||||
INCLUDES 3dparty/cmake
|
||||
SOURCES
|
||||
builddirparameters.cpp builddirparameters.h
|
||||
cmake_global.h
|
||||
@@ -44,4 +45,7 @@ add_qtc_plugin(CMakeProjectManager
|
||||
presetsparser.cpp presetsparser.h
|
||||
presetsmacros.cpp presetsmacros.h
|
||||
projecttreehelper.cpp projecttreehelper.h
|
||||
3rdparty/cmake/cmListFileCache.cxx
|
||||
3rdparty/cmake/cmListFileLexer.c
|
||||
3rdparty/cmake/cmListFileCache.h
|
||||
)
|
||||
|
Reference in New Issue
Block a user