Merge topic 'cmake-gui-capture-output'

209cd475 Help: Add notes for topic 'cmake-gui-capture-output'
d7c69246 execute_process: Send stderr through cmSystemTools::Stderr
92ddf0c9 cmake-gui: Capture cmSystemTools::Stdout and Stderr
f52b5ae3 cmSystemTools: Add callback for Stderr
a9ae1d7a cmSystemTools: Simplify InterruptCallback definition
73b13f56 cmSystemTools: Rename ErrorCallback to MessageCallback
7577a542 cmCTestBuildAndTestHandler: Refactor output capture
b1b4d761 cmCTestBuildAndTestHandler: Refactor local loop var
This commit is contained in:
Brad King 2014-05-16 10:21:05 -04:00 committed by CMake Topic Stage
commit 57151fba6a
9 changed files with 118 additions and 74 deletions

View File

@ -0,0 +1,6 @@
cmake-gui-capture-output
------------------------
* The :manual:`cmake-gui(1)` learned to capture output from child
processes started by the :command:`execute_process` command
and display it in the output window.

View File

@ -156,34 +156,36 @@ void CMakeProgressCallback(const char*msg, float , void * s)
}
//----------------------------------------------------------------------
void CMakeStdoutCallback(const char* m, int len, void* s)
void CMakeOutputCallback(const char* m, size_t len, void* s)
{
std::string* out = (std::string*)s;
out->append(m, len);
}
struct cmSetupOutputCaptureCleanup
//----------------------------------------------------------------------
class cmCTestBuildAndTestCaptureRAII
{
~cmSetupOutputCaptureCleanup()
{
cmSystemTools::SetErrorCallback(0, 0);
cmake& CM;
public:
cmCTestBuildAndTestCaptureRAII(cmake& cm, std::string& s): CM(cm)
{
cmSystemTools::SetMessageCallback(CMakeMessageCallback, &s);
cmSystemTools::SetStdoutCallback(CMakeOutputCallback, &s);
cmSystemTools::SetStderrCallback(CMakeOutputCallback, &s);
this->CM.SetProgressCallback(CMakeProgressCallback, &s);
}
~cmCTestBuildAndTestCaptureRAII()
{
this->CM.SetProgressCallback(0, 0);
cmSystemTools::SetStderrCallback(0, 0);
cmSystemTools::SetStdoutCallback(0, 0);
}
cmSystemTools::SetMessageCallback(0, 0);
}
};
//----------------------------------------------------------------------
int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring)
{
unsigned int k;
std::string cmakeOutString;
cmSystemTools::SetErrorCallback(CMakeMessageCallback, &cmakeOutString);
cmSystemTools::SetStdoutCallback(CMakeStdoutCallback, &cmakeOutString);
// make sure SetStdoutCallback and SetErrorCallback are set to null
// after this function exits so that they do not point at a destroyed
// string cmakeOutString
cmSetupOutputCaptureCleanup cleanup;
static_cast<void>(cleanup);
cmOStringStream out;
// if the generator and make program are not specified then it is an error
if (!this->BuildGenerator.size())
{
@ -197,6 +199,12 @@ int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring)
return 1;
}
cmake cm;
std::string cmakeOutString;
cmCTestBuildAndTestCaptureRAII captureRAII(cm, cmakeOutString);
static_cast<void>(captureRAII);
cmOStringStream out;
if ( this->CTest->GetConfigType().size() == 0 &&
this->ConfigSample.size())
{
@ -233,10 +241,6 @@ int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring)
}
cmSystemTools::ChangeDirectory(this->BinaryDir.c_str());
// should we cmake?
cmake cm;
cm.SetProgressCallback(CMakeProgressCallback, &cmakeOutString);
if(this->BuildNoCMake)
{
// Make the generator available for the Build call below.
@ -369,7 +373,7 @@ int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring)
std::vector<const char*> testCommand;
testCommand.push_back(fullPath.c_str());
for(k=0; k < this->TestCommandArgs.size(); ++k)
for(size_t k=0; k < this->TestCommandArgs.size(); ++k)
{
testCommand.push_back(this->TestCommandArgs[k].c_str());
}
@ -383,7 +387,7 @@ int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring)
cmSystemTools::ChangeDirectory(this->BuildRunDir.c_str());
}
out << "Running test command: \"" << fullPath << "\"";
for(k=0; k < this->TestCommandArgs.size(); ++k)
for(size_t k=0; k < this->TestCommandArgs.size(); ++k)
{
out << " \"" << this->TestCommandArgs[k] << "\"";
}

View File

@ -73,7 +73,8 @@ void onsig(int)
}
void CMakeErrorHandler(const char* message, const char* title, bool&, void* clientData)
void CMakeMessageHandler(const char* message, const char* title, bool&,
void* clientData)
{
cmCursesForm* self = static_cast<cmCursesForm*>( clientData );
self->AddError(message, title);
@ -171,7 +172,7 @@ int main(int argc, char const* const* argv)
return 1;
}
cmSystemTools::SetErrorCallback(CMakeErrorHandler, myform);
cmSystemTools::SetMessageCallback(CMakeMessageHandler, myform);
cmCursesForm::CurrentForm = myform;

View File

@ -35,7 +35,9 @@ QCMake::QCMake(QObject* p)
cmSystemTools::DisableRunCommandOutput();
cmSystemTools::SetRunCommandHideConsole(true);
cmSystemTools::SetErrorCallback(QCMake::errorCallback, this);
cmSystemTools::SetMessageCallback(QCMake::messageCallback, this);
cmSystemTools::SetStdoutCallback(QCMake::stdoutCallback, this);
cmSystemTools::SetStderrCallback(QCMake::stderrCallback, this);
this->CMakeInstance = new cmake;
this->CMakeInstance->SetCMakeEditCommand(
@ -348,14 +350,28 @@ void QCMake::progressCallback(const char* msg, float percent, void* cd)
QCoreApplication::processEvents();
}
void QCMake::errorCallback(const char* msg, const char* /*title*/,
bool& /*stop*/, void* cd)
void QCMake::messageCallback(const char* msg, const char* /*title*/,
bool& /*stop*/, void* cd)
{
QCMake* self = reinterpret_cast<QCMake*>(cd);
emit self->errorMessage(QString::fromLocal8Bit(msg));
QCoreApplication::processEvents();
}
void QCMake::stdoutCallback(const char* msg, size_t len, void* cd)
{
QCMake* self = reinterpret_cast<QCMake*>(cd);
emit self->outputMessage(QString::fromLocal8Bit(msg,int(len)));
QCoreApplication::processEvents();
}
void QCMake::stderrCallback(const char* msg, size_t len, void* cd)
{
QCMake* self = reinterpret_cast<QCMake*>(cd);
emit self->outputMessage(QString::fromLocal8Bit(msg,int(len)));
QCoreApplication::processEvents();
}
QString QCMake::binaryDirectory() const
{
return this->BinaryDirectory;

View File

@ -136,8 +136,10 @@ protected:
static bool interruptCallback(void*);
static void progressCallback(const char* msg, float percent, void* cd);
static void errorCallback(const char* msg, const char* title,
bool&, void* cd);
static void messageCallback(const char* msg, const char* title,
bool&, void* cd);
static void stdoutCallback(const char* msg, size_t len, void* cd);
static void stderrCallback(const char* msg, size_t len, void* cd);
bool SuppressDevWarnings;
bool WarnUninitializedMode;
bool WarnUnusedMode;

View File

@ -256,10 +256,6 @@ bool cmExecuteProcessCommand
// Check the output variables.
bool merge_output = (output_variable == error_variable);
if(error_variable.empty() && !error_quiet)
{
cmsysProcess_SetPipeShared(cp, cmsysProcess_Pipe_STDERR, 1);
}
if(!input_file.empty())
{
cmsysProcess_SetPipeFile(cp, cmsysProcess_Pipe_STDIN, input_file.c_str());
@ -307,7 +303,11 @@ bool cmExecuteProcessCommand
}
else if(p == cmsysProcess_Pipe_STDERR && !error_quiet)
{
if(!error_variable.empty())
if(error_variable.empty())
{
cmSystemTools::Stderr(data, length);
}
else
{
cmExecuteProcessCommandAppend(tempError, data, length);
}

View File

@ -121,13 +121,14 @@ bool cmSystemTools::s_FatalErrorOccured = false;
bool cmSystemTools::s_DisableMessages = false;
bool cmSystemTools::s_ForceUnixPaths = false;
void (*cmSystemTools::s_ErrorCallback)(const char*, const char*,
bool&, void*);
void (*cmSystemTools::s_StdoutCallback)(const char*, int len, void*);
void* cmSystemTools::s_ErrorCallbackClientData = 0;
void* cmSystemTools::s_StdoutCallbackClientData = 0;
bool (*cmSystemTools::s_InterruptCallback)(void*);
void* cmSystemTools::s_InterruptCallbackClientData = 0;
cmSystemTools::MessageCallback cmSystemTools::s_MessageCallback;
cmSystemTools::OutputCallback cmSystemTools::s_StdoutCallback;
cmSystemTools::OutputCallback cmSystemTools::s_StderrCallback;
cmSystemTools::InterruptCallback cmSystemTools::s_InterruptCallback;
void* cmSystemTools::s_MessageCallbackClientData;
void* cmSystemTools::s_StdoutCallbackClientData;
void* cmSystemTools::s_StderrCallbackClientData;
void* cmSystemTools::s_InterruptCallbackClientData;
// replace replace with with as many times as it shows up in source.
// write the result into source.
@ -254,39 +255,48 @@ bool cmSystemTools::GetInterruptFlag()
return false;
}
void cmSystemTools::SetErrorCallback(ErrorCallback f, void* clientData)
void cmSystemTools::SetMessageCallback(MessageCallback f, void* clientData)
{
s_ErrorCallback = f;
s_ErrorCallbackClientData = clientData;
s_MessageCallback = f;
s_MessageCallbackClientData = clientData;
}
void cmSystemTools::SetStdoutCallback(StdoutCallback f, void* clientData)
void cmSystemTools::SetStdoutCallback(OutputCallback f, void* clientData)
{
s_StdoutCallback = f;
s_StdoutCallbackClientData = clientData;
}
void cmSystemTools::SetStderrCallback(OutputCallback f, void* clientData)
{
s_StderrCallback = f;
s_StderrCallbackClientData = clientData;
}
void cmSystemTools::Stdout(const char* s)
{
if(s_StdoutCallback)
cmSystemTools::Stdout(s, strlen(s));
}
void cmSystemTools::Stderr(const char* s)
{
cmSystemTools::Stderr(s, strlen(s));
}
void cmSystemTools::Stderr(const char* s, size_t length)
{
if(s_StderrCallback)
{
(*s_StdoutCallback)(s, static_cast<int>(strlen(s)),
s_StdoutCallbackClientData);
(*s_StderrCallback)(s, length, s_StderrCallbackClientData);
}
else
{
std::cout << s;
std::cout.flush();
std::cerr.write(s, length);
std::cerr.flush();
}
}
void cmSystemTools::Stderr(const char* s, int length)
{
std::cerr.write(s, length);
std::cerr.flush();
}
void cmSystemTools::Stdout(const char* s, int length)
void cmSystemTools::Stdout(const char* s, size_t length)
{
if(s_StdoutCallback)
{
@ -305,10 +315,10 @@ void cmSystemTools::Message(const char* m1, const char *title)
{
return;
}
if(s_ErrorCallback)
if(s_MessageCallback)
{
(*s_ErrorCallback)(m1, title, s_DisableMessages,
s_ErrorCallbackClientData);
(*s_MessageCallback)(m1, title, s_DisableMessages,
s_MessageCallbackClientData);
return;
}
else

View File

@ -57,14 +57,14 @@ public:
*/
static std::string TrimWhitespace(const std::string& s);
typedef void (*ErrorCallback)(const char*, const char*, bool&, void*);
typedef void (*MessageCallback)(const char*, const char*, bool&, void*);
/**
* Set the function used by GUIs to display error messages
* Function gets passed: message as a const char*,
* title as a const char*, and a reference to bool that when
* set to false, will disable furthur messages (cancel).
*/
static void SetErrorCallback(ErrorCallback f, void* clientData=0);
static void SetMessageCallback(MessageCallback f, void* clientData=0);
/**
* Display an error message.
@ -77,14 +77,17 @@ public:
*/
static void Message(const char* m, const char* title=0);
typedef void (*OutputCallback)(const char*, size_t length, void*);
///! Send a string to stdout
static void Stdout(const char* s);
static void Stdout(const char* s, int length);
typedef void (*StdoutCallback)(const char*, int length, void*);
static void SetStdoutCallback(StdoutCallback, void* clientData=0);
static void Stdout(const char* s, size_t length);
static void SetStdoutCallback(OutputCallback, void* clientData=0);
///! Send a string to stderr. Stdout callbacks will not be invoced.
static void Stderr(const char* s, int length);
///! Send a string to stderr
static void Stderr(const char* s);
static void Stderr(const char* s, size_t length);
static void SetStderrCallback(OutputCallback, void* clientData=0);
typedef bool (*InterruptCallback)(void*);
@ -470,11 +473,13 @@ private:
static bool s_FatalErrorOccured;
static bool s_DisableMessages;
static bool s_DisableRunCommandOutput;
static ErrorCallback s_ErrorCallback;
static StdoutCallback s_StdoutCallback;
static MessageCallback s_MessageCallback;
static OutputCallback s_StdoutCallback;
static OutputCallback s_StderrCallback;
static InterruptCallback s_InterruptCallback;
static void* s_ErrorCallbackClientData;
static void* s_MessageCallbackClientData;
static void* s_StdoutCallbackClientData;
static void* s_StderrCallbackClientData;
static void* s_InterruptCallbackClientData;
};

View File

@ -129,8 +129,8 @@ static std::string cmakemainGetStack(void *clientdata)
return msg;
}
static void cmakemainErrorCallback(const char* m, const char*, bool&,
void *clientdata)
static void cmakemainMessageCallback(const char* m, const char*, bool&,
void *clientdata)
{
std::cerr << m << cmakemainGetStack(clientdata) << std::endl << std::flush;
}
@ -310,7 +310,7 @@ int do_cmake(int ac, char const* const* av)
return ret;
}
cmake cm;
cmSystemTools::SetErrorCallback(cmakemainErrorCallback, (void *)&cm);
cmSystemTools::SetMessageCallback(cmakemainMessageCallback, (void *)&cm);
cm.SetProgressCallback(cmakemainProgressCallback, (void *)&cm);
cm.SetWorkingMode(workingMode);