diff --git a/Source/cmExecProgramCommand.cxx b/Source/cmExecProgramCommand.cxx index 431c31679..a5e6e53ce 100644 --- a/Source/cmExecProgramCommand.cxx +++ b/Source/cmExecProgramCommand.cxx @@ -28,8 +28,10 @@ bool cmExecProgramCommand::InitialPass(std::vector const& args) std::string arguments; bool doingargs = false; int count = 0; - std::string variable; - bool havevariable = false; + std::string output_variable; + bool haveoutput_variable = false; + std::string return_variable; + bool havereturn_variable = false; std::string e_command; for(size_t i=0; i < args.size(); ++i) { @@ -37,29 +39,49 @@ bool cmExecProgramCommand::InitialPass(std::vector const& args) { count++; doingargs = false; - havevariable = true; + havereturn_variable = false; + haveoutput_variable = true; } - else if ( havevariable ) + else if ( haveoutput_variable ) { - if ( variable.size() > 0 ) + if ( output_variable.size() > 0 ) { this->SetError("called with incorrect number of arguments"); return false; } - variable = args[i]; + output_variable = args[i]; 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]; + count ++; + } + else if(args[i] == "ARGS") + { + count++; + havereturn_variable = false; + haveoutput_variable = false; + doingargs = true; + } else if(doingargs) { arguments += args[i]; arguments += " "; count++; } - else if(args[i] == "ARGS") - { - count++; - doingargs = true; - } } std::string command; @@ -73,24 +95,32 @@ bool cmExecProgramCommand::InitialPass(std::vector const& args) { command = args[0]; } + int retVal = 0; std::string output; if(args.size() - count == 2) { cmSystemTools::MakeDirectory(args[1].c_str()); - cmSystemTools::RunCommand(command.c_str(), output, + cmSystemTools::RunCommand(command.c_str(), output, retVal, cmSystemTools::ConvertToOutputPath(args[1].c_str()).c_str()); } else { - cmSystemTools::RunCommand(command.c_str(), output); + cmSystemTools::RunCommand(command.c_str(), output, retVal); } - if ( variable.size() > 0 ) + 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"); std::string coutput = std::string(output, first, last); - m_Makefile->AddDefinition(variable.c_str(), coutput.c_str()); + m_Makefile->AddDefinition(output_variable.c_str(), coutput.c_str()); + } + + if ( return_variable.size() > 0 ) + { + char buffer[100]; + sprintf(buffer, "%d", retVal); + m_Makefile->AddDefinition(return_variable.c_str(), buffer); } return true; diff --git a/Source/cmExecProgramCommand.h b/Source/cmExecProgramCommand.h index 39af8b21c..846f2e7f2 100644 --- a/Source/cmExecProgramCommand.h +++ b/Source/cmExecProgramCommand.h @@ -64,11 +64,13 @@ public: virtual const char* GetFullDocumentation() { return - "EXEC_PROGRAM(Executable [Directory to run in] [ARGS arguments to executable] [OUTPUT_VARIABLE var])" + "EXEC_PROGRAM(Executable [Directory to run in] [ARGS arguments to executable] [OUTPUT_VARIABLE var] [RETURN_VALUE var])" "The executable is run in the optionally specified Directory. The executable " "can include arguments if it is double quoted, but it is better to use the " "optional ARGS argument to specify arguments to the program. This is because " - "cmake will then be able to escape spaces in the Executable path."; + "cmake will then be able to escape spaces in the Executable path. An optiona " + "argument OUPUT_VARIABLE specifies a variable to which the output will be set. " + "To capture the return value of the execution, use RETURN_VALUE variable."; } cmTypeMacro(cmExecProgramCommand, cmCommand);