123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333 |
- /*============================================================================
- CMake - Cross Platform Makefile Generator
- Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
- 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 "cmExecProgramCommand.h"
- #include "cmSystemTools.h"
- #include <cmsys/Process.h>
- // cmExecProgramCommand
- bool cmExecProgramCommand
- ::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
- {
- if(args.size() < 1 )
- {
- this->SetError("called with incorrect number of arguments");
- return false;
- }
- std::string arguments;
- bool doingargs = false;
- int count = 0;
- std::string output_variable;
- bool haveoutput_variable = false;
- std::string return_variable;
- bool havereturn_variable = false;
- for(size_t i=0; i < args.size(); ++i)
- {
- if(args[i] == "OUTPUT_VARIABLE")
- {
- count++;
- doingargs = false;
- havereturn_variable = false;
- haveoutput_variable = true;
- }
- else if ( haveoutput_variable )
- {
- if ( output_variable.size() > 0 )
- {
- this->SetError("called with incorrect number of arguments");
- return false;
- }
- output_variable = args[i];
- haveoutput_variable = false;
- count ++;
- }
- else if(args[i] == "RETURN_VALUE")
- {
- count++;
- doingargs = false;
- haveoutput_variable = false;
- havereturn_variable = true;
- }
- else if ( havereturn_variable )
- {
- if ( return_variable.size() > 0 )
- {
- this->SetError("called with incorrect number of arguments");
- return false;
- }
- return_variable = args[i];
- havereturn_variable = false;
- count ++;
- }
- else if(args[i] == "ARGS")
- {
- count++;
- havereturn_variable = false;
- haveoutput_variable = false;
- doingargs = true;
- }
- else if(doingargs)
- {
- arguments += args[i];
- arguments += " ";
- count++;
- }
- }
- std::string command;
- if(arguments.size())
- {
- command = cmSystemTools::ConvertToRunCommandPath(args[0].c_str());
- command += " ";
- command += arguments;
- }
- else
- {
- command = args[0];
- }
- bool verbose = true;
- if(output_variable.size() > 0)
- {
- verbose = false;
- }
- int retVal = 0;
- std::string output;
- bool result = true;
- if(args.size() - count == 2)
- {
- cmSystemTools::MakeDirectory(args[1].c_str());
- result = cmExecProgramCommand::RunCommand(command.c_str(), output, retVal,
- args[1].c_str(), verbose);
- }
- else
- {
- result = cmExecProgramCommand::RunCommand(command.c_str(), output,
- retVal, 0, verbose);
- }
- if(!result)
- {
- retVal = -1;
- }
- if ( output_variable.size() > 0 )
- {
- std::string::size_type first = output.find_first_not_of(" \n\t\r");
- std::string::size_type last = output.find_last_not_of(" \n\t\r");
- if(first == std::string::npos)
- {
- first = 0;
- }
- if(last == std::string::npos)
- {
- last = output.size()-1;
- }
- std::string coutput = std::string(output, first, last-first+1);
- this->Makefile->AddDefinition(output_variable, coutput.c_str());
- }
- if ( return_variable.size() > 0 )
- {
- char buffer[100];
- sprintf(buffer, "%d", retVal);
- this->Makefile->AddDefinition(return_variable, buffer);
- }
- return true;
- }
- bool cmExecProgramCommand::RunCommand(const char* command,
- std::string& output,
- int &retVal,
- const char* dir,
- bool verbose)
- {
- if(cmSystemTools::GetRunCommandOutput())
- {
- verbose = false;
- }
- #if defined(WIN32) && !defined(__CYGWIN__)
- // if the command does not start with a quote, then
- // try to find the program, and if the program can not be
- // found use system to run the command as it must be a built in
- // shell command like echo or dir
- int count = 0;
- std::string shortCmd;
- if(command[0] == '\"')
- {
- // count the number of quotes
- for(const char* s = command; *s != 0; ++s)
- {
- if(*s == '\"')
- {
- count++;
- if(count > 2)
- {
- break;
- }
- }
- }
- // if there are more than two double quotes use
- // GetShortPathName, the cmd.exe program in windows which
- // is used by system fails to execute if there are more than
- // one set of quotes in the arguments
- if(count > 2)
- {
- cmsys::RegularExpression quoted("^\"([^\"]*)\"[ \t](.*)");
- if(quoted.find(command))
- {
- std::string cmd = quoted.match(1);
- std::string args = quoted.match(2);
- if(! cmSystemTools::FileExists(cmd.c_str()) )
- {
- shortCmd = cmd;
- }
- else if(!cmSystemTools::GetShortPath(cmd.c_str(), shortCmd))
- {
- cmSystemTools::Error("GetShortPath failed for " , cmd.c_str());
- return false;
- }
- shortCmd += " ";
- shortCmd += args;
- command = shortCmd.c_str();
- }
- else
- {
- cmSystemTools::Error("Could not parse command line with quotes ",
- command);
- }
- }
- }
- #endif
- // Allocate a process instance.
- cmsysProcess* cp = cmsysProcess_New();
- if(!cp)
- {
- cmSystemTools::Error("Error allocating process instance.");
- return false;
- }
- #if defined(WIN32) && !defined(__CYGWIN__)
- if(dir)
- {
- cmsysProcess_SetWorkingDirectory(cp, dir);
- }
- if(cmSystemTools::GetRunCommandHideConsole())
- {
- cmsysProcess_SetOption(cp, cmsysProcess_Option_HideWindow, 1);
- }
- cmsysProcess_SetOption(cp, cmsysProcess_Option_Verbatim, 1);
- const char* cmd[] = {command, 0};
- cmsysProcess_SetCommand(cp, cmd);
- #else
- std::string commandInDir;
- if(dir)
- {
- commandInDir = "cd \"";
- commandInDir += dir;
- commandInDir += "\" && ";
- commandInDir += command;
- }
- else
- {
- commandInDir = command;
- }
- #ifndef __VMS
- commandInDir += " 2>&1";
- #endif
- command = commandInDir.c_str();
- if(verbose)
- {
- cmSystemTools::Stdout("running ");
- cmSystemTools::Stdout(command);
- cmSystemTools::Stdout("\n");
- }
- fflush(stdout);
- fflush(stderr);
- const char* cmd[] = {"/bin/sh", "-c", command, 0};
- cmsysProcess_SetCommand(cp, cmd);
- #endif
- cmsysProcess_Execute(cp);
- // Read the process output.
- int length;
- char* data;
- int p;
- while((p = cmsysProcess_WaitForData(cp, &data, &length, 0), p))
- {
- if(p == cmsysProcess_Pipe_STDOUT || p == cmsysProcess_Pipe_STDERR)
- {
- if(verbose)
- {
- cmSystemTools::Stdout(data, length);
- }
- output.append(data, length);
- }
- }
- // All output has been read. Wait for the process to exit.
- cmsysProcess_WaitForExit(cp, 0);
- // Check the result of running the process.
- std::string msg;
- switch(cmsysProcess_GetState(cp))
- {
- case cmsysProcess_State_Exited:
- retVal = cmsysProcess_GetExitValue(cp);
- break;
- case cmsysProcess_State_Exception:
- retVal = -1;
- msg += "\nProcess terminated due to: ";
- msg += cmsysProcess_GetExceptionString(cp);
- break;
- case cmsysProcess_State_Error:
- retVal = -1;
- msg += "\nProcess failed because: ";
- msg += cmsysProcess_GetErrorString(cp);
- break;
- case cmsysProcess_State_Expired:
- retVal = -1;
- msg += "\nProcess terminated due to timeout.";
- break;
- }
- if(!msg.empty())
- {
- #if defined(WIN32) && !defined(__CYGWIN__)
- // Old Windows process execution printed this info.
- msg += "\n\nfor command: ";
- msg += command;
- if(dir)
- {
- msg += "\nin dir: ";
- msg += dir;
- }
- msg += "\n";
- if(verbose)
- {
- cmSystemTools::Stdout(msg.c_str());
- }
- output += msg;
- #else
- // Old UNIX process execution only put message in output.
- output += msg;
- #endif
- }
- // Delete the process instance.
- cmsysProcess_Delete(cp);
- return true;
- }
|