diff options
-rw-r--r-- | Source/cmFileCommand.cxx | 85 | ||||
-rw-r--r-- | Tests/RunCMake/File_Configure/AtOnly.cmake | 12 | ||||
-rw-r--r-- | Tests/RunCMake/File_Configure/BadArg-stderr.txt | 4 | ||||
-rw-r--r-- | Tests/RunCMake/File_Configure/BadArgContent-result.txt | 0 | ||||
-rw-r--r-- | Tests/RunCMake/File_Configure/BadArgContent-stderr.txt | 4 | ||||
-rw-r--r-- | Tests/RunCMake/File_Configure/BadArgContent.cmake | 1 | ||||
-rw-r--r-- | Tests/RunCMake/File_Configure/BadArgOutput-result.txt (renamed from Tests/RunCMake/File_Configure/BadArg-result.txt) | 0 | ||||
-rw-r--r-- | Tests/RunCMake/File_Configure/BadArgOutput-stderr.txt | 4 | ||||
-rw-r--r-- | Tests/RunCMake/File_Configure/BadArgOutput.cmake (renamed from Tests/RunCMake/File_Configure/BadArg.cmake) | 0 | ||||
-rw-r--r-- | Tests/RunCMake/File_Configure/EscapeQuotes.cmake | 12 | ||||
-rw-r--r-- | Tests/RunCMake/File_Configure/RunCMakeTest.cmake | 6 | ||||
-rw-r--r-- | Tests/RunCMake/File_Configure/UnrecognizedArgs-result.txt | 1 | ||||
-rw-r--r-- | Tests/RunCMake/File_Configure/UnrecognizedArgs-stderr.txt | 4 | ||||
-rw-r--r-- | Tests/RunCMake/File_Configure/UnrecognizedArgs.cmake | 1 |
14 files changed, 99 insertions, 35 deletions
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx index cd440ad..9467c03 100644 --- a/Source/cmFileCommand.cxx +++ b/Source/cmFileCommand.cxx @@ -2946,17 +2946,60 @@ bool HandleGetRuntimeDependenciesCommand(std::vector<std::string> const& args, bool HandleConfigureCommand(std::vector<std::string> const& args, cmExecutionStatus& status) { - if (args.size() < 5) { - status.SetError("Incorrect arguments to CONFIGURE subcommand."); + struct Arguments + { + std::string Output; + std::string Content; + bool EscapeQuotes = false; + bool AtOnly = false; + std::string NewlineStyle; + }; + + static auto const parser = + cmArgumentParser<Arguments>{} + .Bind("OUTPUT"_s, &Arguments::Output) + .Bind("CONTENT"_s, &Arguments::Content) + .Bind("ESCAPE_QUOTES"_s, &Arguments::EscapeQuotes) + .Bind("@ONLY"_s, &Arguments::AtOnly) + .Bind("NEWLINE_STYLE"_s, &Arguments::NewlineStyle); + + std::vector<std::string> unrecognizedArguments; + std::vector<std::string> keywordsMissingArguments; + std::vector<std::string> parsedKeywords; + auto parsedArgs = + parser.Parse(cmMakeRange(args).advance(1), &unrecognizedArguments, + &keywordsMissingArguments, &parsedKeywords); + + auto argIt = unrecognizedArguments.begin(); + if (argIt != unrecognizedArguments.end()) { + status.SetError( + cmStrCat("CONFIGURE Unrecognized argument: \"", *argIt, "\"")); + cmSystemTools::SetFatalErrorOccured(); return false; } - if (args[1] != "OUTPUT") { - status.SetError("Incorrect arguments to CONFIGURE subcommand."); - return false; + + std::vector<std::string> mandatoryOptions{ "OUTPUT", "CONTENT" }; + for (auto const& e : mandatoryOptions) { + const bool optionHasNoValue = + std::find(keywordsMissingArguments.begin(), + keywordsMissingArguments.end(), + e) != keywordsMissingArguments.end(); + if (optionHasNoValue) { + status.SetError(cmStrCat("CONFIGURE ", e, " option needs a value.")); + cmSystemTools::SetFatalErrorOccured(); + return false; + } } - if (args[3] != "CONTENT") { - status.SetError("Incorrect arguments to CONFIGURE subcommand."); - return false; + + for (auto const& e : mandatoryOptions) { + const bool optionGiven = + std::find(parsedKeywords.begin(), parsedKeywords.end(), e) != + parsedKeywords.end(); + if (!optionGiven) { + status.SetError(cmStrCat("CONFIGURE ", e, " option is mandatory.")); + cmSystemTools::SetFatalErrorOccured(); + return false; + } } std::string errorMessage; @@ -2966,28 +3009,9 @@ bool HandleConfigureCommand(std::vector<std::string> const& args, return false; } - bool escapeQuotes = false; - bool atOnly = false; - for (unsigned int i = 5; i < args.size(); ++i) { - if (args[i] == "@ONLY") { - atOnly = true; - } else if (args[i] == "ESCAPE_QUOTES") { - escapeQuotes = true; - } else if (args[i] == "NEWLINE_STYLE" || args[i] == "LF" || - args[i] == "UNIX" || args[i] == "CRLF" || args[i] == "WIN32" || - args[i] == "DOS") { - /* Options handled by NewLineStyle member above. */ - } else { - status.SetError( - cmStrCat("CONFIGURE Unrecognized argument \"", args[i], "\"")); - return false; - } - } - // Check for generator expressions - const std::string input = args[4]; std::string outputFile = cmSystemTools::CollapseFullPath( - args[2], status.GetMakefile().GetCurrentBinaryDirectory()); + parsedArgs.Output, status.GetMakefile().GetCurrentBinaryDirectory()); std::string::size_type pos = outputFile.find_first_of("<>"); if (pos != std::string::npos) { @@ -3036,12 +3060,13 @@ bool HandleConfigureCommand(std::vector<std::string> const& args, fout.SetCopyIfDifferent(true); // copy input to output and expand variables from input at the same time - std::stringstream sin(input, std::ios::in); + std::stringstream sin(parsedArgs.Content, std::ios::in); std::string inLine; std::string outLine; while (cmSystemTools::GetLineFromStream(sin, inLine)) { outLine.clear(); - makeFile.ConfigureString(inLine, outLine, atOnly, escapeQuotes); + makeFile.ConfigureString(inLine, outLine, parsedArgs.AtOnly, + parsedArgs.EscapeQuotes); fout << outLine << newLineCharacters; } diff --git a/Tests/RunCMake/File_Configure/AtOnly.cmake b/Tests/RunCMake/File_Configure/AtOnly.cmake new file mode 100644 index 0000000..cc5304a --- /dev/null +++ b/Tests/RunCMake/File_Configure/AtOnly.cmake @@ -0,0 +1,12 @@ +set(file_name ${CMAKE_CURRENT_BINARY_DIR}/atonly.txt) +set(var_a "a") +set(var_b "b") +file(CONFIGURE + OUTPUT ${file_name} + CONTENT "-->@var_a@<-- -->${var_b}<--" + @ONLY +) +file(READ ${file_name} file_content) +if(NOT file_content STREQUAL "-->a<-- -->${var_b}<--") + message(FATAL_ERROR "@ONLY doesn't work") +endif() diff --git a/Tests/RunCMake/File_Configure/BadArg-stderr.txt b/Tests/RunCMake/File_Configure/BadArg-stderr.txt deleted file mode 100644 index 5423a28..0000000 --- a/Tests/RunCMake/File_Configure/BadArg-stderr.txt +++ /dev/null @@ -1,4 +0,0 @@ -CMake Error at BadArg.cmake:[0-9]+ \(file\): - file Incorrect arguments to CONFIGURE subcommand. -Call Stack \(most recent call first\): - CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/File_Configure/BadArgContent-result.txt b/Tests/RunCMake/File_Configure/BadArgContent-result.txt new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/Tests/RunCMake/File_Configure/BadArgContent-result.txt diff --git a/Tests/RunCMake/File_Configure/BadArgContent-stderr.txt b/Tests/RunCMake/File_Configure/BadArgContent-stderr.txt new file mode 100644 index 0000000..a6ea314 --- /dev/null +++ b/Tests/RunCMake/File_Configure/BadArgContent-stderr.txt @@ -0,0 +1,4 @@ +CMake Error at BadArgContent.cmake:[0-9]+ \(file\): + file CONFIGURE CONTENT option needs a value. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/File_Configure/BadArgContent.cmake b/Tests/RunCMake/File_Configure/BadArgContent.cmake new file mode 100644 index 0000000..282dc18 --- /dev/null +++ b/Tests/RunCMake/File_Configure/BadArgContent.cmake @@ -0,0 +1 @@ +file(CONFIGURE CONTENT) diff --git a/Tests/RunCMake/File_Configure/BadArg-result.txt b/Tests/RunCMake/File_Configure/BadArgOutput-result.txt index d00491f..d00491f 100644 --- a/Tests/RunCMake/File_Configure/BadArg-result.txt +++ b/Tests/RunCMake/File_Configure/BadArgOutput-result.txt diff --git a/Tests/RunCMake/File_Configure/BadArgOutput-stderr.txt b/Tests/RunCMake/File_Configure/BadArgOutput-stderr.txt new file mode 100644 index 0000000..b5a924c --- /dev/null +++ b/Tests/RunCMake/File_Configure/BadArgOutput-stderr.txt @@ -0,0 +1,4 @@ +CMake Error at BadArgOutput.cmake:[0-9]+ \(file\): + file CONFIGURE OUTPUT option needs a value. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/File_Configure/BadArg.cmake b/Tests/RunCMake/File_Configure/BadArgOutput.cmake index 7c7fcda..7c7fcda 100644 --- a/Tests/RunCMake/File_Configure/BadArg.cmake +++ b/Tests/RunCMake/File_Configure/BadArgOutput.cmake diff --git a/Tests/RunCMake/File_Configure/EscapeQuotes.cmake b/Tests/RunCMake/File_Configure/EscapeQuotes.cmake new file mode 100644 index 0000000..1136c87 --- /dev/null +++ b/Tests/RunCMake/File_Configure/EscapeQuotes.cmake @@ -0,0 +1,12 @@ +set(file_name ${CMAKE_CURRENT_BINARY_DIR}/escape_quotes.txt) +set(var "\t") +set(ref "${var}") +file(CONFIGURE + CONTENT "-->@ref@<--" + OUTPUT ${file_name} + ESCAPE_QUOTES +) +file(READ ${file_name} file_content) +if(NOT file_content MATCHES "^-->\t<--$") + message(FATAL_ERROR "ESCAPE_QUOTES doesn't work") +endif() diff --git a/Tests/RunCMake/File_Configure/RunCMakeTest.cmake b/Tests/RunCMake/File_Configure/RunCMakeTest.cmake index e79de79..5022985 100644 --- a/Tests/RunCMake/File_Configure/RunCMakeTest.cmake +++ b/Tests/RunCMake/File_Configure/RunCMakeTest.cmake @@ -1,10 +1,14 @@ include(RunCMake) run_cmake(AngleBracketsContent) -run_cmake(BadArg) +run_cmake(BadArgOutput) +run_cmake(BadArgContent) run_cmake(BadArgGeneratorExpressionOutput) +run_cmake(UnrecognizedArgs) run_cmake(DirOutput) run_cmake(NewLineStyle-NoArg) run_cmake(NewLineStyle-ValidArg) run_cmake(NewLineStyle-WrongArg) run_cmake(SubDir) +run_cmake(AtOnly) +run_cmake(EscapeQuotes) diff --git a/Tests/RunCMake/File_Configure/UnrecognizedArgs-result.txt b/Tests/RunCMake/File_Configure/UnrecognizedArgs-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/File_Configure/UnrecognizedArgs-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/File_Configure/UnrecognizedArgs-stderr.txt b/Tests/RunCMake/File_Configure/UnrecognizedArgs-stderr.txt new file mode 100644 index 0000000..1dd1a20 --- /dev/null +++ b/Tests/RunCMake/File_Configure/UnrecognizedArgs-stderr.txt @@ -0,0 +1,4 @@ +CMake Error at UnrecognizedArgs.cmake:[0-9]+ \(file\): + file CONFIGURE Unrecognized argument: "INPUT" +Call Stack \(most recent call first\): + CMakeLists.txt:[0-9]+ \(include\) diff --git a/Tests/RunCMake/File_Configure/UnrecognizedArgs.cmake b/Tests/RunCMake/File_Configure/UnrecognizedArgs.cmake new file mode 100644 index 0000000..93ea7b5 --- /dev/null +++ b/Tests/RunCMake/File_Configure/UnrecognizedArgs.cmake @@ -0,0 +1 @@ +file(CONFIGURE INPUT) |