summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorCristian Adam <cristian.adam@gmail.com>2020-02-27 20:20:22 +0100
committerBrad King <brad.king@kitware.com>2020-03-03 08:42:13 -0500
commit598b676b5e77540b366b01b3c10154c2a633d23c (patch)
treeeb3aaea48e3c1743835a74be111ca64ee4a9a4e5 /Source
parentc58b9c5ab94d674c76a17e6154f05e0e8c5c37d1 (diff)
downloadcmake-598b676b5e77540b366b01b3c10154c2a633d23c.tar.gz
cmake_command: Add command to EVAL a CMake script as a string
Diffstat (limited to 'Source')
-rw-r--r--Source/LexerParser/cmListFileLexer.c14
-rw-r--r--Source/LexerParser/cmListFileLexer.in.l14
-rw-r--r--Source/cmCMakeCommand.cxx27
-rw-r--r--Source/cmListFileCache.cxx51
-rw-r--r--Source/cmListFileCache.h3
-rw-r--r--Source/cmMakefile.cxx21
-rw-r--r--Source/cmMakefile.h3
7 files changed, 100 insertions, 33 deletions
diff --git a/Source/LexerParser/cmListFileLexer.c b/Source/LexerParser/cmListFileLexer.c
index 15dcda04a0..ec7424c4f9 100644
--- a/Source/LexerParser/cmListFileLexer.c
+++ b/Source/LexerParser/cmListFileLexer.c
@@ -2787,7 +2787,7 @@ int cmListFileLexer_SetString(cmListFileLexer* lexer, const char* text)
/*--------------------------------------------------------------------------*/
cmListFileLexer_Token* cmListFileLexer_Scan(cmListFileLexer* lexer)
{
- if (!lexer->file) {
+ if (!lexer->file && !lexer->string_buffer) {
return 0;
}
if (cmListFileLexer_yylex(lexer->scanner, lexer)) {
@@ -2801,21 +2801,13 @@ cmListFileLexer_Token* cmListFileLexer_Scan(cmListFileLexer* lexer)
/*--------------------------------------------------------------------------*/
long cmListFileLexer_GetCurrentLine(cmListFileLexer* lexer)
{
- if (lexer->file) {
- return lexer->line;
- } else {
- return 0;
- }
+ return lexer->line;
}
/*--------------------------------------------------------------------------*/
long cmListFileLexer_GetCurrentColumn(cmListFileLexer* lexer)
{
- if (lexer->file) {
- return lexer->column;
- } else {
- return 0;
- }
+ return lexer->column;
}
/*--------------------------------------------------------------------------*/
diff --git a/Source/LexerParser/cmListFileLexer.in.l b/Source/LexerParser/cmListFileLexer.in.l
index fdf14d2d38..94cf8a5943 100644
--- a/Source/LexerParser/cmListFileLexer.in.l
+++ b/Source/LexerParser/cmListFileLexer.in.l
@@ -500,7 +500,7 @@ int cmListFileLexer_SetString(cmListFileLexer* lexer, const char* text)
/*--------------------------------------------------------------------------*/
cmListFileLexer_Token* cmListFileLexer_Scan(cmListFileLexer* lexer)
{
- if (!lexer->file) {
+ if (!lexer->file && !lexer->string_buffer) {
return 0;
}
if (cmListFileLexer_yylex(lexer->scanner, lexer)) {
@@ -514,21 +514,13 @@ cmListFileLexer_Token* cmListFileLexer_Scan(cmListFileLexer* lexer)
/*--------------------------------------------------------------------------*/
long cmListFileLexer_GetCurrentLine(cmListFileLexer* lexer)
{
- if (lexer->file) {
- return lexer->line;
- } else {
- return 0;
- }
+ return lexer->line;
}
/*--------------------------------------------------------------------------*/
long cmListFileLexer_GetCurrentColumn(cmListFileLexer* lexer)
{
- if (lexer->file) {
- return lexer->column;
- } else {
- return 0;
- }
+ return lexer->column;
}
/*--------------------------------------------------------------------------*/
diff --git a/Source/cmCMakeCommand.cxx b/Source/cmCMakeCommand.cxx
index 56990864b0..c11a00364c 100644
--- a/Source/cmCMakeCommand.cxx
+++ b/Source/cmCMakeCommand.cxx
@@ -2,11 +2,14 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCMakeCommand.h"
+#include <algorithm>
#include <cstddef>
#include "cmExecutionStatus.h"
#include "cmListFileCache.h"
#include "cmMakefile.h"
+#include "cmRange.h"
+#include "cmStringAlgorithms.h"
bool cmCMakeCommand(std::vector<std::string> const& args,
cmExecutionStatus& status)
@@ -19,6 +22,8 @@ bool cmCMakeCommand(std::vector<std::string> const& args,
cmMakefile& makefile = status.GetMakefile();
cmListFileContext context = makefile.GetExecutionContext();
+ bool result = false;
+
if (args[0] == "INVOKE") {
if (args.size() == 1) {
status.SetError("called with incorrect number of arguments");
@@ -39,9 +44,25 @@ bool cmCMakeCommand(std::vector<std::string> const& args,
func.Arguments.emplace_back(lfarg);
}
- return makefile.ExecuteCommand(func, status);
+ result = makefile.ExecuteCommand(func, status);
+ } else if (args[0] == "EVAL") {
+ if (args.size() < 2) {
+ status.SetError("called with incorrect number of arguments");
+ return false;
+ }
+
+ auto code_iter = std::find(args.begin(), args.end(), "CODE");
+ if (code_iter == args.end()) {
+ status.SetError("called without CODE argument");
+ return false;
+ }
+
+ const std::string code = cmJoin(cmMakeRange(++code_iter, args.end()), " ");
+ result = makefile.ReadListFileAsString(
+ code, cmStrCat(context.FilePath, ":", context.Line, ":EVAL"));
+ } else {
+ status.SetError("called with unknown meta-operation");
}
- status.SetError("called with unknown meta-operation");
- return false;
+ return result;
}
diff --git a/Source/cmListFileCache.cxx b/Source/cmListFileCache.cxx
index 47679c9322..7ebb02f492 100644
--- a/Source/cmListFileCache.cxx
+++ b/Source/cmListFileCache.cxx
@@ -26,13 +26,15 @@ cmCommandContext::cmCommandName& cmCommandContext::cmCommandName::operator=(
struct cmListFileParser
{
cmListFileParser(cmListFile* lf, cmListFileBacktrace lfbt,
- cmMessenger* messenger, const char* filename);
+ cmMessenger* messenger);
~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();
+ bool ParseFile(const char* filename);
+ bool ParseString(const char* str, const char* virtual_filename);
+ bool Parse();
bool ParseFunction(const char* name, long line);
bool AddArgument(cmListFileLexer_Token* token,
cmListFileArgument::Delimiter delim);
@@ -51,12 +53,11 @@ struct cmListFileParser
};
cmListFileParser::cmListFileParser(cmListFile* lf, cmListFileBacktrace lfbt,
- cmMessenger* messenger,
- const char* filename)
+ cmMessenger* messenger)
: ListFile(lf)
, Backtrace(std::move(lfbt))
, Messenger(messenger)
- , FileName(filename)
+ , FileName(nullptr)
, Lexer(cmListFileLexer_New())
{
}
@@ -83,8 +84,10 @@ void cmListFileParser::IssueError(const std::string& text) const
cmSystemTools::SetFatalErrorOccured();
}
-bool cmListFileParser::ParseFile()
+bool cmListFileParser::ParseFile(const char* filename)
{
+ this->FileName = filename;
+
// Open the file.
cmListFileLexer_BOM bom;
if (!cmListFileLexer_SetFileName(this->Lexer, this->FileName, &bom)) {
@@ -107,6 +110,24 @@ bool cmListFileParser::ParseFile()
return false;
}
+ return 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.");
+ return false;
+ }
+
+ return Parse();
+}
+
+bool cmListFileParser::Parse()
+{
// Use a simple recursive-descent parser to process the token
// stream.
bool haveNewline = true;
@@ -155,8 +176,22 @@ bool cmListFile::ParseFile(const char* filename, cmMessenger* messenger,
bool parseError = false;
{
- cmListFileParser parser(this, lfbt, messenger, filename);
- parseError = !parser.ParseFile();
+ 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 parseError = false;
+
+ {
+ cmListFileParser parser(this, lfbt, messenger);
+ parseError = !parser.ParseString(str, virtual_filename);
}
return !parseError;
diff --git a/Source/cmListFileCache.h b/Source/cmListFileCache.h
index 9cae8277b2..89902ff30b 100644
--- a/Source/cmListFileCache.h
+++ b/Source/cmListFileCache.h
@@ -184,6 +184,9 @@ 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);
+
std::vector<cmListFileFunction> Functions;
};
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index ed627f8e72..94d99b7a4a 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -684,6 +684,27 @@ bool cmMakefile::ReadListFile(const std::string& filename)
return true;
}
+bool cmMakefile::ReadListFileAsString(const std::string& content,
+ const std::string& virtualFileName)
+{
+ std::string filenametoread = cmSystemTools::CollapseFullPath(
+ virtualFileName, this->GetCurrentSourceDirectory());
+
+ ListFileScope scope(this, filenametoread);
+
+ cmListFile listFile;
+ if (!listFile.ParseString(content.c_str(), virtualFileName.c_str(),
+ this->GetMessenger(), this->Backtrace)) {
+ return false;
+ }
+
+ this->ReadListFile(listFile, filenametoread);
+ if (cmSystemTools::GetFatalErrorOccured()) {
+ scope.Quiet();
+ }
+ return true;
+}
+
void cmMakefile::ReadListFile(cmListFile const& listFile,
std::string const& filenametoread)
{
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index f1a68c2902..9c6dca62db 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -117,6 +117,9 @@ public:
bool ReadListFile(const std::string& filename);
+ bool ReadListFileAsString(const std::string& content,
+ const std::string& virtualFileName);
+
bool ReadDependentFile(const std::string& filename,
bool noPolicyScope = true);