diff options
Diffstat (limited to 'Source/CTest/cmProcess.cxx')
-rw-r--r-- | Source/CTest/cmProcess.cxx | 238 |
1 files changed, 100 insertions, 138 deletions
diff --git a/Source/CTest/cmProcess.cxx b/Source/CTest/cmProcess.cxx index 167b992c9..f4ec6da29 100644 --- a/Source/CTest/cmProcess.cxx +++ b/Source/CTest/cmProcess.cxx @@ -1,21 +1,15 @@ -/*============================================================================ - CMake - Cross Platform Makefile Generator - Copyright 2000-2009 Kitware, Inc., Insight Software Consortium +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#include "cmProcess.h" - Distributed under the OSI-approved BSD License (the "License"); - see accompanying file Copyright.txt for details. - - This software is distributed WITHOUT ANY WARRANTY; without even the - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the License for more information. -============================================================================*/ - -#include <cmProcess.h> -#include <cmSystemTools.h> +#include "cmConfigure.h" +#include "cmProcessOutput.h" +#include "cmSystemTools.h" +#include <iostream> cmProcess::cmProcess() { - this->Process = 0; + this->Process = CM_NULLPTR; this->Timeout = 0; this->TotalTime = 0; this->ExitValue = 0; @@ -39,49 +33,43 @@ void cmProcess::SetCommandArguments(std::vector<std::string> const& args) bool cmProcess::StartProcess() { - if(this->Command.size() == 0) - { + if (this->Command.empty()) { return false; - } + } this->StartTime = cmSystemTools::GetTime(); this->ProcessArgs.clear(); // put the command as arg0 this->ProcessArgs.push_back(this->Command.c_str()); // now put the command arguments in - for(std::vector<std::string>::iterator i = this->Arguments.begin(); - i != this->Arguments.end(); ++i) - { + for (std::vector<std::string>::iterator i = this->Arguments.begin(); + i != this->Arguments.end(); ++i) { this->ProcessArgs.push_back(i->c_str()); - } - this->ProcessArgs.push_back(0); // null terminate the list + } + this->ProcessArgs.push_back(CM_NULLPTR); // null terminate the list this->Process = cmsysProcess_New(); cmsysProcess_SetCommand(this->Process, &*this->ProcessArgs.begin()); - if(this->WorkingDirectory.size()) - { + if (!this->WorkingDirectory.empty()) { cmsysProcess_SetWorkingDirectory(this->Process, this->WorkingDirectory.c_str()); - } + } cmsysProcess_SetTimeout(this->Process, this->Timeout); + cmsysProcess_SetOption(this->Process, cmsysProcess_Option_MergeOutput, 1); cmsysProcess_Execute(this->Process); - return (cmsysProcess_GetState(this->Process) - == cmsysProcess_State_Executing); + return (cmsysProcess_GetState(this->Process) == + cmsysProcess_State_Executing); } -//---------------------------------------------------------------------------- bool cmProcess::Buffer::GetLine(std::string& line) { // Scan for the next newline. - for(size_type sz = this->size(); this->Last != sz; ++this->Last) - { - if((*this)[this->Last] == '\n' || (*this)[this->Last] == '\0') - { + for (size_type sz = this->size(); this->Last != sz; ++this->Last) { + if ((*this)[this->Last] == '\n' || (*this)[this->Last] == '\0') { // Extract the range first..last as a line. const char* text = &*this->begin() + this->First; size_type length = this->Last - this->First; - while(length && text[length-1] == '\r') - { - length --; - } + while (length && text[length - 1] == '\r') { + length--; + } line.assign(text, length); // Start a new range for the next line. @@ -90,87 +78,70 @@ bool cmProcess::Buffer::GetLine(std::string& line) // Return the line extracted. return true; - } } + } // Available data have been exhausted without a newline. - if(this->First != 0) - { + if (this->First != 0) { // Move the partial line to the beginning of the buffer. this->erase(this->begin(), this->begin() + this->First); this->First = 0; this->Last = this->size(); - } + } return false; } -//---------------------------------------------------------------------------- bool cmProcess::Buffer::GetLast(std::string& line) { // Return the partial last line, if any. - if(!this->empty()) - { + if (!this->empty()) { line.assign(&*this->begin(), this->size()); this->First = this->Last = 0; this->clear(); return true; - } + } return false; } -//---------------------------------------------------------------------------- int cmProcess::GetNextOutputLine(std::string& line, double timeout) { - for(;;) - { + cmProcessOutput processOutput(cmProcessOutput::UTF8); + std::string strdata; + for (;;) { // Look for lines already buffered. - if(this->StdOut.GetLine(line)) - { + if (this->Output.GetLine(line)) { return cmsysProcess_Pipe_STDOUT; - } - else if(this->StdErr.GetLine(line)) - { - return cmsysProcess_Pipe_STDERR; - } + } // Check for more data from the process. char* data; int length; int p = cmsysProcess_WaitForData(this->Process, &data, &length, &timeout); - if(p == cmsysProcess_Pipe_Timeout) - { + if (p == cmsysProcess_Pipe_Timeout) { return cmsysProcess_Pipe_Timeout; - } - else if(p == cmsysProcess_Pipe_STDOUT) - { - this->StdOut.insert(this->StdOut.end(), data, data+length); - } - else if(p == cmsysProcess_Pipe_STDERR) - { - this->StdErr.insert(this->StdErr.end(), data, data+length); - } - else // p == cmsysProcess_Pipe_None - { + } + if (p == cmsysProcess_Pipe_STDOUT) { + processOutput.DecodeText(data, length, strdata); + this->Output.insert(this->Output.end(), strdata.begin(), strdata.end()); + } else { // p == cmsysProcess_Pipe_None // The process will provide no more data. break; - } } + } + processOutput.DecodeText(std::string(), strdata); + if (!strdata.empty()) { + this->Output.insert(this->Output.end(), strdata.begin(), strdata.end()); + } // Look for partial last lines. - if(this->StdOut.GetLast(line)) - { + if (this->Output.GetLast(line)) { return cmsysProcess_Pipe_STDOUT; - } - else if(this->StdErr.GetLast(line)) - { - return cmsysProcess_Pipe_STDERR; - } + } // No more data. Wait for process exit. - if(!cmsysProcess_WaitForExit(this->Process, &timeout)) - { + if (!cmsysProcess_WaitForExit(this->Process, &timeout)) { return cmsysProcess_Pipe_Timeout; - } + } // Record exit information. this->ExitValue = cmsysProcess_GetExitValue(this->Process); @@ -179,10 +150,9 @@ int cmProcess::GetNextOutputLine(std::string& line, double timeout) // negative. If someone changed the system clock while the process was // running this may be even more. Make sure not to report a negative // duration here. - if (this->TotalTime <= 0.0) - { + if (this->TotalTime <= 0.0) { this->TotalTime = 0.0; - } + } // std::cerr << "Time to run: " << this->TotalTime << "\n"; return cmsysProcess_Pipe_None; } @@ -190,89 +160,81 @@ int cmProcess::GetNextOutputLine(std::string& line, double timeout) // return the process status int cmProcess::GetProcessStatus() { - if(!this->Process) - { + if (!this->Process) { return cmsysProcess_State_Exited; - } + } return cmsysProcess_GetState(this->Process); } int cmProcess::ReportStatus() { int result = 1; - switch(cmsysProcess_GetState(this->Process)) - { - case cmsysProcess_State_Starting: - { - std::cerr << "cmProcess: Never started " - << this->Command << " process.\n"; - } break; - case cmsysProcess_State_Error: - { + switch (cmsysProcess_GetState(this->Process)) { + case cmsysProcess_State_Starting: { + std::cerr << "cmProcess: Never started " << this->Command + << " process.\n"; + } break; + case cmsysProcess_State_Error: { std::cerr << "cmProcess: Error executing " << this->Command - << " process: " - << cmsysProcess_GetErrorString(this->Process) + << " process: " << cmsysProcess_GetErrorString(this->Process) << "\n"; - } break; - case cmsysProcess_State_Exception: - { + } break; + case cmsysProcess_State_Exception: { std::cerr << "cmProcess: " << this->Command - << " process exited with an exception: "; - switch(cmsysProcess_GetExitException(this->Process)) - { - case cmsysProcess_Exception_None: - { + << " process exited with an exception: "; + switch (cmsysProcess_GetExitException(this->Process)) { + case cmsysProcess_Exception_None: { std::cerr << "None"; - } break; - case cmsysProcess_Exception_Fault: - { + } break; + case cmsysProcess_Exception_Fault: { std::cerr << "Segmentation fault"; - } break; - case cmsysProcess_Exception_Illegal: - { + } break; + case cmsysProcess_Exception_Illegal: { std::cerr << "Illegal instruction"; - } break; - case cmsysProcess_Exception_Interrupt: - { + } break; + case cmsysProcess_Exception_Interrupt: { std::cerr << "Interrupted by user"; - } break; - case cmsysProcess_Exception_Numerical: - { + } break; + case cmsysProcess_Exception_Numerical: { std::cerr << "Numerical exception"; - } break; - case cmsysProcess_Exception_Other: - { + } break; + case cmsysProcess_Exception_Other: { std::cerr << "Unknown"; - } break; - } + } break; + } std::cerr << "\n"; - } break; - case cmsysProcess_State_Executing: - { - std::cerr << "cmProcess: Never terminated " << - this->Command << " process.\n"; - } break; - case cmsysProcess_State_Exited: - { + } break; + case cmsysProcess_State_Executing: { + std::cerr << "cmProcess: Never terminated " << this->Command + << " process.\n"; + } break; + case cmsysProcess_State_Exited: { result = cmsysProcess_GetExitValue(this->Process); std::cerr << "cmProcess: " << this->Command - << " process exited with code " - << result << "\n"; - } break; - case cmsysProcess_State_Expired: - { + << " process exited with code " << result << "\n"; + } break; + case cmsysProcess_State_Expired: { std::cerr << "cmProcess: killed " << this->Command << " process due to timeout.\n"; - } break; - case cmsysProcess_State_Killed: - { + } break; + case cmsysProcess_State_Killed: { std::cerr << "cmProcess: killed " << this->Command << " process.\n"; - } break; - } + } break; + } return result; +} +void cmProcess::ChangeTimeout(double t) +{ + this->Timeout = t; + cmsysProcess_SetTimeout(this->Process, this->Timeout); } +void cmProcess::ResetStartTime() +{ + cmsysProcess_ResetStartTime(this->Process); + this->StartTime = cmSystemTools::GetTime(); +} int cmProcess::GetExitException() { |