From 8a31793c89be483bcf6d44fff0785b894172e35a Mon Sep 17 00:00:00 2001 From: Andy Cedilnik Date: Sun, 3 Aug 2003 22:32:15 -0400 Subject: [PATCH] ENH: Add back the kwsysProcess RunCommand, now is in parallel --- Source/cmSystemTools.cxx | 131 ++++++++++++++++++++++++++++++++++++++- Source/cmSystemTools.h | 17 +++++ 2 files changed, 147 insertions(+), 1 deletion(-) diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index dd75b8c49..51ec308a3 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx @@ -22,6 +22,7 @@ #include #include +#include // support for realpath call #ifndef _WIN32 @@ -292,7 +293,135 @@ bool cmSystemTools::IsOff(const char* val) v == "N" || cmSystemTools::IsNOTFOUND(v.c_str()) || v == "IGNORE"); } - +bool cmSystemTools::RunSingleCommand( + const char* command, + std::string* output, + int *retVal, + const char* dir, + bool verbose, + int timeout) +{ + if(s_DisableRunCommandOutput) + { + verbose = false; + } + + std::vector args; + std::string arg; + + // Split the command into an argv array. + for(const char* c = command; *c;) + { + // Skip over whitespace. + while(*c == ' ' || *c == '\t') + { + ++c; + } + arg = ""; + if(*c == '"') + { + // Parse a quoted argument. + ++c; + while(*c && *c != '"') + { + if(*c == '\\') + { + ++c; + if(*c) + { + arg.append(1, *c); + ++c; + } + } + else + { + arg.append(1, *c); + ++c; + } + } + if(*c) + { + ++c; + } + args.push_back(arg); + } + else if(*c) + { + // Parse an unquoted argument. + while(*c && *c != ' ' && *c != '\t') + { + arg.append(1, *c); + ++c; + } + args.push_back(arg); + } + } + + std::vector argv; + for(std::vector::const_iterator a = args.begin(); + a != args.end(); ++a) + { + argv.push_back(a->c_str()); + } + argv.push_back(0); + + if(argv.size() < 2) + { + return false; + } + + if ( output ) + { + *output = ""; + } + cmsysProcess* cp = cmsysProcess_New(); + cmsysProcess_SetCommand(cp, &*argv.begin()); + cmsysProcess_SetWorkingDirectory(cp, dir); + cmsysProcess_SetTimeout(cp, timeout); + cmsysProcess_Execute(cp); + + char* data; + int length; + while(cmsysProcess_WaitForData(cp, (cmsysProcess_Pipe_STDOUT | + cmsysProcess_Pipe_STDERR), + &data, &length, 0)) + { + if ( output ) + { + output->append(data, length); + } + if(verbose) + { + std::cout.write(data, length); + } + } + + cmsysProcess_WaitForExit(cp, 0); + + bool result = true; + if(cmsysProcess_GetState(cp) == cmsysProcess_State_Exited) + { + if ( retVal ) + { + *retVal = cmsysProcess_GetExitValue(cp); + } + else + { + if ( cmsysProcess_GetExitValue(cp) != 0 ) + { + result = false; + } + } + } + else + { + result = false; + } + + cmsysProcess_Delete(cp); + + return result; +} bool cmSystemTools::RunCommand(const char* command, std::string& output, const char* dir, diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h index a25b9d996..7f26b2558 100644 --- a/Source/cmSystemTools.h +++ b/Source/cmSystemTools.h @@ -162,6 +162,23 @@ public: static bool RunCommand(const char* command, std::string& output, int &retVal, const char* directory = 0, bool verbose = true, int timeout = 0); + /** + * Run a single executable command and put the stdout and stderr + * in output. + * + * If verbose is false, no user-viewable output from the program + * being run will be generated. + * + * If timeout is specified, the command will be terminated after + * timeout expires. Timeout is specified in seconds. + * + * Argument retVal should be a pointer to the location where the + * exit code will be stored. If the retVal is not specified and + * the program exits with a code other than 0, then the this + * function will return false. + */ + static bool RunSingleCommand(const char* command, std::string* output = 0, + int* retVal = 0, const char* dir = 0, bool verbose = true, int timeout = 0); static void EnableMessages() { s_DisableMessages = false; } static void DisableMessages() { s_DisableMessages = true; }