diff options
Diffstat (limited to 'Source/cmExecuteProcessCommand.cxx')
-rw-r--r-- | Source/cmExecuteProcessCommand.cxx | 71 |
1 files changed, 61 insertions, 10 deletions
diff --git a/Source/cmExecuteProcessCommand.cxx b/Source/cmExecuteProcessCommand.cxx index 8c10dbe..39e774e 100644 --- a/Source/cmExecuteProcessCommand.cxx +++ b/Source/cmExecuteProcessCommand.cxx @@ -7,6 +7,7 @@ #include <sstream> #include <stdio.h> +#include "cmAlgorithms.h" #include "cmMakefile.h" #include "cmProcessOutput.h" #include "cmSystemTools.h" @@ -15,7 +16,7 @@ class cmExecutionStatus; static bool cmExecuteProcessCommandIsWhitespace(char c) { - return (isspace((int)c) || c == '\n' || c == '\r'); + return (isspace(static_cast<int>(c)) || c == '\n' || c == '\r'); } void cmExecuteProcessCommandFixText(std::vector<char>& output, @@ -31,7 +32,7 @@ bool cmExecuteProcessCommand::InitialPass(std::vector<std::string> const& args, this->SetError("called with incorrect number of arguments"); return false; } - std::vector<std::vector<const char*> > cmds; + std::vector<std::vector<const char*>> cmds; std::string arguments; bool doing_command = false; size_t command_index = 0; @@ -46,6 +47,7 @@ bool cmExecuteProcessCommand::InitialPass(std::vector<std::string> 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<std::string> 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()) { @@ -160,13 +170,13 @@ bool cmExecuteProcessCommand::InitialPass(std::vector<std::string> const& args, this->SetError(" called with no COMMAND argument."); return false; } - for (unsigned int i = 0; i < cmds.size(); ++i) { - if (cmds[i].empty()) { + for (auto& cmd : cmds) { + if (cmd.empty()) { this->SetError(" given COMMAND argument with no value."); return false; } // Add the null terminating pointer to the command argument list. - cmds[i].push_back(CM_NULLPTR); + cmd.push_back(nullptr); } // Parse the timeout string. @@ -182,8 +192,8 @@ bool cmExecuteProcessCommand::InitialPass(std::vector<std::string> const& args, cmsysProcess* cp = cmsysProcess_New(); // Set the command sequence. - for (unsigned int i = 0; i < cmds.size(); ++i) { - cmsysProcess_AddCommand(cp, &*cmds[i].begin()); + for (auto const& cmd : cmds) { + cmsysProcess_AddCommand(cp, &*cmd.begin()); } // Set the process working directory. @@ -234,7 +244,7 @@ bool cmExecuteProcessCommand::InitialPass(std::vector<std::string> const& args, int p; cmProcessOutput processOutput(encoding); std::string strdata; - while ((p = cmsysProcess_WaitForData(cp, &data, &length, CM_NULLPTR), p)) { + while ((p = cmsysProcess_WaitForData(cp, &data, &length, nullptr), p)) { // Put the output in the right place. if (p == cmsysProcess_Pipe_STDOUT && !output_quiet) { if (output_variable.empty()) { @@ -266,7 +276,7 @@ bool cmExecuteProcessCommand::InitialPass(std::vector<std::string> const& args, } // All output has been read. Wait for the process to exit. - cmsysProcess_WaitForExit(cp, CM_NULLPTR); + cmsysProcess_WaitForExit(cp, nullptr); processOutput.DecodeText(tempOutput, tempOutput); processOutput.DecodeText(tempError, tempError); @@ -287,7 +297,7 @@ bool cmExecuteProcessCommand::InitialPass(std::vector<std::string> 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<std::string> const& args, break; } } + // Store the result of running the processes. + if (!results_variable.empty()) { + switch (cmsysProcess_GetState(cp)) { + case cmsysProcess_State_Exited: { + std::vector<std::string> res; + for (size_t i = 0; i < cmds.size(); ++i) { + switch (cmsysProcess_GetStateByIndex(cp, static_cast<int>(i))) { + case kwsysProcess_StateByIndex_Exited: { + int exitCode = + cmsysProcess_GetExitValueByIndex(cp, static_cast<int>(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<int>(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); |