Merge topic 'split-stdout-stderr'

a343bc1 RunSingleCommand: Avoid assignment in condition
642f100 RunSingleCommand: Add a OUTPUT_NORMAL flag.
856a9e4 RunSingleCommand: Replace verbose boolean with enum
4096066 RunSingleCommand: Fix indentation
This commit is contained in:
David Cole 2011-08-02 15:09:57 -04:00 committed by CMake Topic Stage
commit 2444d6f55e
15 changed files with 103 additions and 53 deletions

View File

@ -33,7 +33,7 @@
//---------------------------------------------------------------------- //----------------------------------------------------------------------
cmCPackGenerator::cmCPackGenerator() cmCPackGenerator::cmCPackGenerator()
{ {
this->GeneratorVerbose = false; this->GeneratorVerbose = cmSystemTools::OUTPUT_NONE;
this->MakefileMap = 0; this->MakefileMap = 0;
this->Logger = 0; this->Logger = 0;
this->componentPackageMethod = ONE_PACKAGE_PER_GROUP; this->componentPackageMethod = ONE_PACKAGE_PER_GROUP;

View File

@ -14,6 +14,7 @@
#define cmCPackGenerator_h #define cmCPackGenerator_h
#include "cmObject.h" #include "cmObject.h"
#include "cmSystemTools.h"
#include <map> #include <map>
#include <vector> #include <vector>
@ -57,7 +58,9 @@ public:
/** /**
* If verbose then more information is printed out * If verbose then more information is printed out
*/ */
void SetVerbose(bool val) { this->GeneratorVerbose = val; } void SetVerbose(bool val)
{ this->GeneratorVerbose = val ?
cmSystemTools::OUTPUT_MERGE : cmSystemTools::OUTPUT_NONE; }
/** /**
* Do the actual whole package processing. * Do the actual whole package processing.
@ -194,7 +197,7 @@ protected:
virtual cmCPackComponentGroup* GetComponentGroup(const char *projectName, virtual cmCPackComponentGroup* GetComponentGroup(const char *projectName,
const char* name); const char* name);
bool GeneratorVerbose; cmSystemTools::OutputOption GeneratorVerbose;
std::string Name; std::string Name;
std::string InstallPath; std::string InstallPath;

View File

@ -786,7 +786,8 @@ CreateComponentDescription(cmCPackComponent *component,
std::string output; std::string output;
int retVal = -1; int retVal = -1;
int res = cmSystemTools::RunSingleCommand(cmd.c_str(), &output, &retVal, int res = cmSystemTools::RunSingleCommand(cmd.c_str(), &output, &retVal,
dirName.c_str(), false, 0); dirName.c_str(),
cmSystemTools::OUTPUT_NONE, 0);
if ( !res || retVal ) if ( !res || retVal )
{ {
std::string tmpFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY"); std::string tmpFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");

View File

@ -18,7 +18,7 @@
//---------------------------------------------------------------------- //----------------------------------------------------------------------
cmCTestGenericHandler::cmCTestGenericHandler() cmCTestGenericHandler::cmCTestGenericHandler()
{ {
this->HandlerVerbose = false; this->HandlerVerbose = cmSystemTools::OUTPUT_NONE;
this->CTest = 0; this->CTest = 0;
this->SubmitIndex = 0; this->SubmitIndex = 0;
this->AppendXML = false; this->AppendXML = false;

View File

@ -16,6 +16,7 @@
#include "cmObject.h" #include "cmObject.h"
#include "cmCTest.h" #include "cmCTest.h"
#include "cmSystemTools.h" //OutputOption
class cmMakefile; class cmMakefile;
class cmCTestCommand; class cmCTestCommand;
@ -31,7 +32,9 @@ public:
/** /**
* If verbose then more informaiton is printed out * If verbose then more informaiton is printed out
*/ */
void SetVerbose(bool val) { this->HandlerVerbose = val; } void SetVerbose(bool val)
{ this->HandlerVerbose = val ?
cmSystemTools::OUTPUT_MERGE : cmSystemTools::OUTPUT_NONE; }
/** /**
* Populate internals from CTest custom scripts * Populate internals from CTest custom scripts
@ -91,7 +94,7 @@ protected:
bool StartLogFile(const char* name, cmGeneratedFileStream& xofs); bool StartLogFile(const char* name, cmGeneratedFileStream& xofs);
bool AppendXML; bool AppendXML;
bool HandlerVerbose; cmSystemTools::OutputOption HandlerVerbose;
cmCTest *CTest; cmCTest *CTest;
t_StringToString Options; t_StringToString Options;
t_StringToString PersistentOptions; t_StringToString PersistentOptions;

View File

@ -1301,7 +1301,8 @@ int cmCTestTestHandler::ExecuteCommands(std::vector<cmStdString>& vec)
int retVal = 0; int retVal = 0;
cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Run command: " << *it cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Run command: " << *it
<< std::endl); << std::endl);
if ( !cmSystemTools::RunSingleCommand(it->c_str(), 0, &retVal, 0, true if ( !cmSystemTools::RunSingleCommand(it->c_str(), 0, &retVal, 0,
cmSystemTools::OUTPUT_MERGE
/*this->Verbose*/) || retVal != 0 ) /*this->Verbose*/) || retVal != 0 )
{ {
cmCTestLog(this->CTest, ERROR_MESSAGE, "Problem running command: " cmCTestLog(this->CTest, ERROR_MESSAGE, "Problem running command: "

View File

@ -1136,7 +1136,7 @@ int cmGlobalGenerator::Build(
const char *config, const char *config,
bool clean, bool fast, bool clean, bool fast,
double timeout, double timeout,
bool verbose, cmSystemTools::OutputOption outputflag,
const char* extraOptions, const char* extraOptions,
std::vector<std::string> const& nativeOptions) std::vector<std::string> const& nativeOptions)
{ {
@ -1176,7 +1176,7 @@ int cmGlobalGenerator::Build(
} }
if (!cmSystemTools::RunSingleCommand(cleanCommand.c_str(), outputPtr, if (!cmSystemTools::RunSingleCommand(cleanCommand.c_str(), outputPtr,
&retVal, 0, verbose, timeout)) &retVal, 0, outputflag, timeout))
{ {
cmSystemTools::SetRunCommandHideConsole(hideconsole); cmSystemTools::SetRunCommandHideConsole(hideconsole);
cmSystemTools::Error("Generator: execution of make clean failed."); cmSystemTools::Error("Generator: execution of make clean failed.");
@ -1217,7 +1217,7 @@ int cmGlobalGenerator::Build(
} }
if (!cmSystemTools::RunSingleCommand(command, outputPtr, if (!cmSystemTools::RunSingleCommand(command, outputPtr,
&retVal, 0, verbose, timeout)) &retVal, 0, outputflag, timeout))
{ {
cmSystemTools::SetRunCommandHideConsole(hideconsole); cmSystemTools::SetRunCommandHideConsole(hideconsole);
cmSystemTools::Error cmSystemTools::Error

View File

@ -17,7 +17,7 @@
#include "cmTarget.h" // For cmTargets #include "cmTarget.h" // For cmTargets
#include "cmTargetDepend.h" // For cmTargetDependSet #include "cmTargetDepend.h" // For cmTargetDependSet
#include "cmSystemTools.h" // for cmSystemTools::OutputOption
class cmake; class cmake;
class cmMakefile; class cmMakefile;
class cmLocalGenerator; class cmLocalGenerator;
@ -102,7 +102,8 @@ public:
std::string *output, std::string *output,
const char *makeProgram, const char *config, const char *makeProgram, const char *config,
bool clean, bool fast, bool clean, bool fast,
double timeout, bool verbose=false, double timeout,
cmSystemTools::OutputOption outputflag=cmSystemTools::OUTPUT_NONE,
const char* extraOptions = 0, const char* extraOptions = 0,
std::vector<std::string> const& nativeOptions = std::vector<std::string> const& nativeOptions =
std::vector<std::string>()); std::vector<std::string>());

View File

@ -63,7 +63,7 @@ bool cmSiteNameCommand
{ {
std::string host; std::string host;
cmSystemTools::RunSingleCommand(hostname_cmd.c_str(), cmSystemTools::RunSingleCommand(hostname_cmd.c_str(),
&host, 0, 0, false); &host, 0, 0, cmSystemTools::OUTPUT_NONE);
// got the hostname // got the hostname
if (host.length()) if (host.length())

View File

@ -247,6 +247,12 @@ void cmSystemTools::Stdout(const char* s)
} }
} }
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, int length)
{ {
if(s_StdoutCallback) if(s_StdoutCallback)
@ -577,7 +583,7 @@ std::vector<cmStdString> cmSystemTools::ParseArguments(const char* command)
bool cmSystemTools::RunSingleCommand(std::vector<cmStdString>const& command, bool cmSystemTools::RunSingleCommand(std::vector<cmStdString>const& command,
std::string* output , std::string* output ,
int* retVal , const char* dir , int* retVal , const char* dir ,
bool verbose , OutputOption outputflag ,
double timeout ) double timeout )
{ {
std::vector<const char*> argv; std::vector<const char*> argv;
@ -599,38 +605,54 @@ bool cmSystemTools::RunSingleCommand(std::vector<cmStdString>const& command,
{ {
cmsysProcess_SetOption(cp, cmsysProcess_Option_HideWindow, 1); cmsysProcess_SetOption(cp, cmsysProcess_Option_HideWindow, 1);
} }
cmsysProcess_SetTimeout(cp, timeout); cmsysProcess_SetTimeout(cp, timeout);
cmsysProcess_Execute(cp); cmsysProcess_Execute(cp);
std::vector<char> tempOutput; std::vector<char> tempOutput;
char* data; char* data;
int length; int length;
if ( output || verbose ) int pipe;
if ( output || outputflag != OUTPUT_NONE )
{ {
while(cmsysProcess_WaitForData(cp, &data, &length, 0)) while((pipe = cmsysProcess_WaitForData(cp, &data, &length, 0)) > 0)
{
if(output || verbose)
{ {
// Translate NULL characters in the output into valid text. if(output || outputflag != OUTPUT_NONE)
// Visual Studio 7 puts these characters in the output of its
// build process.
for(int i=0; i < length; ++i)
{ {
if(data[i] == '\0') // Translate NULL characters in the output into valid text.
// Visual Studio 7 puts these characters in the output of its
// build process.
for(int i=0; i < length; ++i)
{ {
data[i] = ' '; if(data[i] == '\0')
{
data[i] = ' ';
}
}
}
if ( output )
{
tempOutput.insert(tempOutput.end(), data, data+length);
}
if(outputflag != OUTPUT_NONE)
{
if(outputflag == OUTPUT_MERGE)
{
cmSystemTools::Stdout(data, length);
}
else
{
if(pipe == cmsysProcess_Pipe_STDERR)
{
cmSystemTools::Stderr(data, length);
}
else if(pipe == cmsysProcess_Pipe_STDOUT)
{
cmSystemTools::Stdout(data, length);
}
} }
} }
} }
if ( output )
{
tempOutput.insert(tempOutput.end(), data, data+length);
}
if(verbose)
{
cmSystemTools::Stdout(data, length);
}
}
} }
cmsysProcess_WaitForExit(cp, 0); cmsysProcess_WaitForExit(cp, 0);
@ -657,7 +679,7 @@ bool cmSystemTools::RunSingleCommand(std::vector<cmStdString>const& command,
else if(cmsysProcess_GetState(cp) == cmsysProcess_State_Exception) else if(cmsysProcess_GetState(cp) == cmsysProcess_State_Exception)
{ {
const char* exception_str = cmsysProcess_GetExceptionString(cp); const char* exception_str = cmsysProcess_GetExceptionString(cp);
if ( verbose ) if ( outputflag != OUTPUT_NONE )
{ {
std::cerr << exception_str << std::endl; std::cerr << exception_str << std::endl;
} }
@ -670,7 +692,7 @@ bool cmSystemTools::RunSingleCommand(std::vector<cmStdString>const& command,
else if(cmsysProcess_GetState(cp) == cmsysProcess_State_Error) else if(cmsysProcess_GetState(cp) == cmsysProcess_State_Error)
{ {
const char* error_str = cmsysProcess_GetErrorString(cp); const char* error_str = cmsysProcess_GetErrorString(cp);
if ( verbose ) if ( outputflag != OUTPUT_NONE )
{ {
std::cerr << error_str << std::endl; std::cerr << error_str << std::endl;
} }
@ -683,7 +705,7 @@ bool cmSystemTools::RunSingleCommand(std::vector<cmStdString>const& command,
else if(cmsysProcess_GetState(cp) == cmsysProcess_State_Expired) else if(cmsysProcess_GetState(cp) == cmsysProcess_State_Expired)
{ {
const char* error_str = "Process terminated due to timeout\n"; const char* error_str = "Process terminated due to timeout\n";
if ( verbose ) if ( outputflag != OUTPUT_NONE )
{ {
std::cerr << error_str << std::endl; std::cerr << error_str << std::endl;
} }
@ -703,12 +725,12 @@ bool cmSystemTools::RunSingleCommand(
std::string* output, std::string* output,
int *retVal, int *retVal,
const char* dir, const char* dir,
bool verbose, OutputOption outputflag,
double timeout) double timeout)
{ {
if(s_DisableRunCommandOutput) if(s_DisableRunCommandOutput)
{ {
verbose = false; outputflag = OUTPUT_NONE;
} }
std::vector<cmStdString> args = cmSystemTools::ParseArguments(command); std::vector<cmStdString> args = cmSystemTools::ParseArguments(command);
@ -718,7 +740,7 @@ bool cmSystemTools::RunSingleCommand(
return false; return false;
} }
return cmSystemTools::RunSingleCommand(args, output,retVal, return cmSystemTools::RunSingleCommand(args, output,retVal,
dir, verbose, timeout); dir, outputflag, timeout);
} }
bool cmSystemTools::RunCommand(const char* command, bool cmSystemTools::RunCommand(const char* command,
std::string& output, std::string& output,

View File

@ -75,6 +75,9 @@ public:
typedef void (*StdoutCallback)(const char*, int length, void*); typedef void (*StdoutCallback)(const char*, int length, void*);
static void SetStdoutCallback(StdoutCallback, void* clientData=0); static void SetStdoutCallback(StdoutCallback, void* clientData=0);
///! Send a string to stderr. Stdout callbacks will not be invoced.
static void Stderr(const char* s, int length);
///! Return true if there was an error at any point. ///! Return true if there was an error at any point.
static bool GetErrorOccuredFlag() static bool GetErrorOccuredFlag()
{ {
@ -191,11 +194,13 @@ public:
int &retVal, const char* directory = 0, int &retVal, const char* directory = 0,
bool verbose = true, int timeout = 0); bool verbose = true, int timeout = 0);
/** /**
* Run a single executable command and put the stdout and stderr * Run a single executable command
* in output.
* *
* If verbose is false, no user-viewable output from the program * Output is controlled with outputflag. If outputflag is OUTPUT_NONE, no
* being run will be generated. * user-viewable output from the program being run will be generated.
* OUTPUT_MERGE is the legacy behaviour where stdout and stderr are merged
* into stdout. OUTPUT_NORMAL passes through the output to stdout/stderr as
* it was received.
* *
* If timeout is specified, the command will be terminated after * If timeout is specified, the command will be terminated after
* timeout expires. Timeout is specified in seconds. * timeout expires. Timeout is specified in seconds.
@ -210,9 +215,15 @@ public:
* it into this function or it will not work. The command must be correctly * it into this function or it will not work. The command must be correctly
* escaped for this to with spaces. * escaped for this to with spaces.
*/ */
enum OutputOption
{
OUTPUT_NONE = 0,
OUTPUT_MERGE,
OUTPUT_NORMAL
};
static bool RunSingleCommand(const char* command, std::string* output = 0, static bool RunSingleCommand(const char* command, std::string* output = 0,
int* retVal = 0, const char* dir = 0, int* retVal = 0, const char* dir = 0,
bool verbose = true, OutputOption outputflag = OUTPUT_MERGE,
double timeout = 0.0); double timeout = 0.0);
/** /**
* In this version of RunSingleCommand, command[0] should be * In this version of RunSingleCommand, command[0] should be
@ -222,7 +233,7 @@ public:
static bool RunSingleCommand(std::vector<cmStdString> const& command, static bool RunSingleCommand(std::vector<cmStdString> const& command,
std::string* output = 0, std::string* output = 0,
int* retVal = 0, const char* dir = 0, int* retVal = 0, const char* dir = 0,
bool verbose = true, OutputOption outputflag = OUTPUT_MERGE,
double timeout = 0.0); double timeout = 0.0);
/** /**

View File

@ -194,7 +194,7 @@ void cmTryRunCommand::RunExecutable(const std::string& runArgs,
int timeout = 0; int timeout = 0;
bool worked = cmSystemTools::RunSingleCommand(finalCommand.c_str(), bool worked = cmSystemTools::RunSingleCommand(finalCommand.c_str(),
out, &retVal, out, &retVal,
0, false, timeout); 0, cmSystemTools::OUTPUT_NONE, timeout);
// set the run var // set the run var
char retChar[1000]; char retChar[1000];
if (worked) if (worked)

View File

@ -1299,7 +1299,7 @@ int cmake::ExecuteCMakeCommand(std::vector<std::string>& args)
int retval = 0; int retval = 0;
int timeout = 0; int timeout = 0;
if ( cmSystemTools::RunSingleCommand(command.c_str(), 0, &retval, if ( cmSystemTools::RunSingleCommand(command.c_str(), 0, &retval,
directory.c_str(), true, timeout) ) directory.c_str(), cmSystemTools::OUTPUT_MERGE, timeout) )
{ {
return retval; return retval;
} }
@ -3984,7 +3984,7 @@ bool cmake::RunCommand(const char* comment,
// use rc command to create .res file // use rc command to create .res file
cmSystemTools::RunSingleCommand(command, cmSystemTools::RunSingleCommand(command,
&output, &output,
&retCode, 0, false); &retCode, 0, cmSystemTools::OUTPUT_NONE);
// always print the output of the command, unless // always print the output of the command, unless
// it is the dumb rc command banner, but if the command // it is the dumb rc command banner, but if the command
// returned an error code then print the output anyway as // returned an error code then print the output anyway as
@ -4302,7 +4302,8 @@ int cmake::Build(const std::string& dir,
const std::string& target, const std::string& target,
const std::string& config, const std::string& config,
const std::vector<std::string>& nativeOptions, const std::vector<std::string>& nativeOptions,
bool clean) bool clean,
cmSystemTools::OutputOption outputflag)
{ {
if(!cmSystemTools::FileIsDirectory(dir.c_str())) if(!cmSystemTools::FileIsDirectory(dir.c_str()))
{ {
@ -4344,7 +4345,7 @@ int cmake::Build(const std::string& dir,
projName.c_str(), target.c_str(), projName.c_str(), target.c_str(),
&output, &output,
makeProgram.c_str(), makeProgram.c_str(),
config.c_str(), clean, false, 0, true, config.c_str(), clean, false, 0, outputflag,
0, nativeOptions); 0, nativeOptions);
} }

View File

@ -364,7 +364,8 @@ class cmake
const std::string& target, const std::string& target,
const std::string& config, const std::string& config,
const std::vector<std::string>& nativeOptions, const std::vector<std::string>& nativeOptions,
bool clean); bool clean,
cmSystemTools::OutputOption outputflag);
void UnwatchUnusedCli(const char* var); void UnwatchUnusedCli(const char* var);
void WatchUnusedCli(const char* var); void WatchUnusedCli(const char* var);

View File

@ -62,6 +62,7 @@ static const char * cmDocumentationDescription[][3] =
" --config <cfg> = For multi-configuration tools, choose <cfg>.\n" \ " --config <cfg> = For multi-configuration tools, choose <cfg>.\n" \
" --clean-first = Build target 'clean' first, then build.\n" \ " --clean-first = Build target 'clean' first, then build.\n" \
" (To clean only, use --target 'clean'.)\n" \ " (To clean only, use --target 'clean'.)\n" \
" --use-stderr = Don't merge stdout/stderr.\n" \
" -- = Pass remaining options to the native tool.\n" " -- = Pass remaining options to the native tool.\n"
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -568,6 +569,7 @@ static int do_build(int ac, char** av)
std::string dir; std::string dir;
std::vector<std::string> nativeOptions; std::vector<std::string> nativeOptions;
bool clean = false; bool clean = false;
cmSystemTools::OutputOption outputflag = cmSystemTools::OUTPUT_MERGE;
enum Doing { DoingNone, DoingDir, DoingTarget, DoingConfig, DoingNative}; enum Doing { DoingNone, DoingDir, DoingTarget, DoingConfig, DoingNative};
Doing doing = DoingDir; Doing doing = DoingDir;
@ -590,6 +592,10 @@ static int do_build(int ac, char** av)
clean = true; clean = true;
doing = DoingNone; doing = DoingNone;
} }
else if(strcmp(av[i], "--use-stderr") == 0)
{
outputflag = cmSystemTools::OUTPUT_NORMAL;
}
else if(strcmp(av[i], "--") == 0) else if(strcmp(av[i], "--") == 0)
{ {
doing = DoingNative; doing = DoingNative;
@ -635,6 +641,6 @@ static int do_build(int ac, char** av)
} }
cmake cm; cmake cm;
return cm.Build(dir, target, config, nativeOptions, clean); return cm.Build(dir, target, config, nativeOptions, clean, outputflag);
#endif #endif
} }