From d6051ca39e2ac8e5afc8f6308fd1bda7d1e8c17b Mon Sep 17 00:00:00 2001 From: Adam Weisi Date: Thu, 13 Apr 2017 19:10:04 +0200 Subject: execute_process: Add option to get results of every child Add a `RESULTS_VARIABLE` option to get the results of all children in a pipeline of one or more `COMMAND`s. --- Source/cmExecuteProcessCommand.cxx | 53 +++++++++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) (limited to 'Source/cmExecuteProcessCommand.cxx') diff --git a/Source/cmExecuteProcessCommand.cxx b/Source/cmExecuteProcessCommand.cxx index 8c10dbe29a..435adca2cf 100644 --- a/Source/cmExecuteProcessCommand.cxx +++ b/Source/cmExecuteProcessCommand.cxx @@ -7,6 +7,7 @@ #include #include +#include "cmAlgorithms.h" #include "cmMakefile.h" #include "cmProcessOutput.h" #include "cmSystemTools.h" @@ -46,6 +47,7 @@ bool cmExecuteProcessCommand::InitialPass(std::vector const& args, std::string output_variable; std::string error_variable; std::string result_variable; + std::string results_variable; std::string working_directory; cmProcessOutput::Encoding encoding = cmProcessOutput::None; for (size_t i = 0; i < args.size(); ++i) { @@ -77,6 +79,14 @@ bool cmExecuteProcessCommand::InitialPass(std::vector const& args, this->SetError(" called with no value for RESULT_VARIABLE."); return false; } + } else if (args[i] == "RESULTS_VARIABLE") { + doing_command = false; + if (++i < args.size()) { + results_variable = args[i]; + } else { + this->SetError(" called with no value for RESULTS_VARIABLE."); + return false; + } } else if (args[i] == "WORKING_DIRECTORY") { doing_command = false; if (++i < args.size()) { @@ -287,7 +297,7 @@ bool cmExecuteProcessCommand::InitialPass(std::vector const& args, switch (cmsysProcess_GetState(cp)) { case cmsysProcess_State_Exited: { int v = cmsysProcess_GetExitValue(cp); - char buf[100]; + char buf[16]; sprintf(buf, "%d", v); this->Makefile->AddDefinition(result_variable, buf); } break; @@ -305,6 +315,47 @@ bool cmExecuteProcessCommand::InitialPass(std::vector const& args, break; } } + // Store the result of running the processes. + if (!results_variable.empty()) { + switch (cmsysProcess_GetState(cp)) { + case cmsysProcess_State_Exited: { + std::vector res; + for (size_t i = 0; i < cmds.size(); ++i) { + switch (cmsysProcess_GetStateByIndex(cp, static_cast(i))) { + case kwsysProcess_StateByIndex_Exited: { + int exitCode = + cmsysProcess_GetExitValueByIndex(cp, static_cast(i)); + char buf[16]; + sprintf(buf, "%d", exitCode); + res.push_back(buf); + } break; + case kwsysProcess_StateByIndex_Exception: + res.push_back(cmsysProcess_GetExceptionStringByIndex( + cp, static_cast(i))); + break; + case kwsysProcess_StateByIndex_Error: + default: + res.push_back("Error getting the child return code"); + break; + } + } + this->Makefile->AddDefinition(results_variable, + cmJoin(res, ";").c_str()); + } break; + case cmsysProcess_State_Exception: + this->Makefile->AddDefinition(results_variable, + cmsysProcess_GetExceptionString(cp)); + break; + case cmsysProcess_State_Error: + this->Makefile->AddDefinition(results_variable, + cmsysProcess_GetErrorString(cp)); + break; + case cmsysProcess_State_Expired: + this->Makefile->AddDefinition(results_variable, + "Process terminated due to timeout"); + break; + } + } // Delete the process instance. cmsysProcess_Delete(cp); -- cgit v1.2.1