summaryrefslogtreecommitdiff
path: root/Source/CTest/cmProcess.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/CTest/cmProcess.cxx')
-rw-r--r--Source/CTest/cmProcess.cxx238
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()
{