diff options
Diffstat (limited to 'Source/cmExecuteProcessCommand.cxx')
-rw-r--r-- | Source/cmExecuteProcessCommand.cxx | 58 |
1 files changed, 57 insertions, 1 deletions
diff --git a/Source/cmExecuteProcessCommand.cxx b/Source/cmExecuteProcessCommand.cxx index 9c53bdf..14147e0 100644 --- a/Source/cmExecuteProcessCommand.cxx +++ b/Source/cmExecuteProcessCommand.cxx @@ -7,8 +7,10 @@ #include <cstdio> #include <iostream> #include <memory> +#include <sstream> #include <vector> +#include <cm/string_view> #include <cmext/algorithm> #include <cmext/string_view> @@ -63,6 +65,7 @@ bool cmExecuteProcessCommand(std::vector<std::string> const& args, bool EchoOutputVariable = false; bool EchoErrorVariable = false; std::string Encoding; + std::string CommandErrorIsFatal; }; static auto const parser = @@ -86,7 +89,8 @@ bool cmExecuteProcessCommand(std::vector<std::string> const& args, &Arguments::ErrorStripTrailingWhitespace) .Bind("ENCODING"_s, &Arguments::Encoding) .Bind("ECHO_OUTPUT_VARIABLE"_s, &Arguments::EchoOutputVariable) - .Bind("ECHO_ERROR_VARIABLE"_s, &Arguments::EchoErrorVariable); + .Bind("ECHO_ERROR_VARIABLE"_s, &Arguments::EchoErrorVariable) + .Bind("COMMAND_ERROR_IS_FATAL"_s, &Arguments::CommandErrorIsFatal); std::vector<std::string> unparsedArguments; std::vector<std::string> keywordsMissingValue; @@ -131,6 +135,14 @@ bool cmExecuteProcessCommand(std::vector<std::string> const& args, return false; } } + + if (!arguments.CommandErrorIsFatal.empty()) { + if (arguments.CommandErrorIsFatal != "ANY"_s && + arguments.CommandErrorIsFatal != "LAST"_s) { + status.SetError("COMMAND_ERROR_IS_FATAL option can be ANY or LAST"); + return false; + } + } // Create a process instance. std::unique_ptr<cmsysProcess, void (*)(cmsysProcess*)> cp_ptr( cmsysProcess_New(), cmsysProcess_Delete); @@ -363,6 +375,50 @@ bool cmExecuteProcessCommand(std::vector<std::string> const& args, } } + if (arguments.CommandErrorIsFatal == "ANY"_s) { + if (cmsysProcess_GetState(cp) == cmsysProcess_State_Exited) { + std::vector<int> failedIndexes; + for (int i = 0; i < static_cast<int>(arguments.Commands.size()); ++i) { + if (cmsysProcess_GetStateByIndex(cp, i) == + kwsysProcess_StateByIndex_Exited) { + int exitCode = cmsysProcess_GetExitValueByIndex(cp, i); + if (exitCode) { + failedIndexes.push_back(i); + } + } + } + if (!failedIndexes.empty()) { + std::ostringstream oss; + oss << "failed command indexes: "; + for (auto i = 0u; i < failedIndexes.size(); i++) { + if (i == failedIndexes.size() - 1) { + oss << failedIndexes[i] + 1; + } else { + oss << failedIndexes[i] + 1 << ", "; + } + } + status.SetError(oss.str()); + cmSystemTools::SetFatalErrorOccured(); + return false; + } + } + } + + if (arguments.CommandErrorIsFatal == "LAST"_s) { + if (cmsysProcess_GetState(cp) == cmsysProcess_State_Exited) { + int lastIndex = static_cast<int>(arguments.Commands.size() - 1); + if (cmsysProcess_GetStateByIndex(cp, lastIndex) == + kwsysProcess_StateByIndex_Exited) { + int exitCode = cmsysProcess_GetExitValueByIndex(cp, lastIndex); + if (exitCode) { + status.SetError("last command failed"); + cmSystemTools::SetFatalErrorOccured(); + return false; + } + } + } + } + return true; } |