diff options
Diffstat (limited to 'Source')
55 files changed, 1901 insertions, 655 deletions
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index dacc0e09bb..71ed0d46ee 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -205,6 +205,8 @@ IF (WIN32) cmLocalVisualStudio6Generator.h cmLocalVisualStudio7Generator.cxx cmLocalVisualStudio7Generator.h + cmLocalVisualStudioGenerator.cxx + cmLocalVisualStudioGenerator.h cmWin32ProcessExecution.cxx cmWin32ProcessExecution.h ) @@ -324,11 +326,11 @@ IF(BUILD_MFCDialog) ENDIF(BUILD_MFCDialog) # WX Widgets GUI -OPTION(CMAKE_BUILD_WX_DIALOG "Build wxWidgets dialog for CMake" FALSE) -MARK_AS_ADVANCED(CMAKE_BUILD_WX_DIALOG) -IF(CMAKE_BUILD_WX_DIALOG) +OPTION(BUILD_WXDialog "Build wxWidgets dialog for CMake" FALSE) +MARK_AS_ADVANCED(BUILD_WXDialog) +IF(BUILD_WXDialog) SUBDIRS(WXDialog) -ENDIF(CMAKE_BUILD_WX_DIALOG) +ENDIF(BUILD_WXDialog) # Testing IF (NOT DART_ROOT) @@ -502,6 +504,16 @@ IF(BUILD_TESTING) --build-two-config --test-command conly) + ADD_TEST(CxxOnly ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMake_SOURCE_DIR}/Tests/CxxOnly" + "${CMake_BINARY_DIR}/Tests/CxxOnly" + --build-generator ${CMAKE_TEST_GENERATOR} + --build-project cxxonly + --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM} + --build-two-config + --test-command cxxonly) + ADD_TEST(MacroTest ${CMAKE_CTEST_COMMAND} --build-and-test "${CMake_SOURCE_DIR}/Tests/MacroTest" @@ -962,8 +974,9 @@ IF(BUILD_TESTING) --build-target install # --build-target package --build-options "-DCMAKE_INSTALL_PREFIX:PATH=${BundleTestInstallDir}" + "-DCMake_SOURCE_DIR:PATH=${CMAKE_SOURCE_DIR}" --test-command - ${BundleTestInstallDir}/Application/BundleTestExe.app/Contents/MacOS/BundleTestExe) + ${BundleTestInstallDir}/Application/SecondBundleExe.app/Contents/MacOS/SecondBundleExe) ADD_TEST(objc++ ${CMAKE_CTEST_COMMAND} --build-and-test @@ -1063,9 +1076,8 @@ IF(BUILD_TESTING) ENDIF(JAVA_COMPILE AND JAVA_RUNTIME AND JAVA_ARCHIVE AND NOT MINGW) ENDIF(NOT CMAKE_TEST_GENERATOR MATCHES "Xcode") - - IF (CMAKE_WXWINDOWS_WXCONFIG_EXECUTABLE OR WXWINDOWS_INCLUDE_DIR) - # Will be set if the wxwindows gui is on + IF(BUILD_WXDialog AND wxWidgets_CONFIG_EXECUTABLE) + # Will be set if the WX gui is on ADD_TEST(UseWX ${CMAKE_CTEST_COMMAND} --build-and-test "${CMake_SOURCE_DIR}/Tests/UseWX" @@ -1073,11 +1085,11 @@ IF(BUILD_TESTING) --build-generator ${CMAKE_TEST_GENERATOR} --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM} --build-exe-dir ${CMake_BINARY_DIR}/Tests/UseWX - --build-project UsewxWindows - --build-options -DCMAKE_WXWINDOWS_WXCONFIG_EXECUTABLE:FILEPATH=${CMAKE_WXWINDOWS_WXCONFIG_EXECUTABLE} + --build-project UsewxWidgets + --build-options -DwxWidgets_CONFIG_EXECUTABLE=${wxWidgets_CONFIG_EXECUTABLE} --test-command UseWX ) - ENDIF (CMAKE_WXWINDOWS_WXCONFIG_EXECUTABLE OR WXWINDOWS_INCLUDE_DIR) + ENDIF(BUILD_WXDialog AND wxWidgets_CONFIG_EXECUTABLE) IF(UNIX) STRING(COMPARE EQUAL "${CMAKE_INSTALL_PREFIX}" "${CMake_BINARY_DIR}/Tests/TestShellInstall/Prefix" diff --git a/Source/CPack/cmCPackGenericGenerator.cxx b/Source/CPack/cmCPackGenericGenerator.cxx index f4e51b3af5..fac48dc950 100644 --- a/Source/CPack/cmCPackGenericGenerator.cxx +++ b/Source/CPack/cmCPackGenericGenerator.cxx @@ -142,6 +142,7 @@ int cmCPackGenericGenerator::PrepareNames() { this->SetOptionIfNotSet("CPACK_STRIP_COMMAND", pkgPath.c_str()); } + this->SetOptionIfNotSet("CPACK_REMOVE_TOPLEVEL_DIRECTORY", "1"); return 1; } @@ -150,23 +151,6 @@ int cmCPackGenericGenerator::PrepareNames() int cmCPackGenericGenerator::InstallProject() { cmCPackLogger(cmCPackLog::LOG_OUTPUT, "Install projects" << std::endl); - std::vector<cmsys::RegularExpression> ignoreFilesRegex; - const char* cpackIgnoreFiles = this->GetOption("CPACK_IGNORE_FILES"); - if ( cpackIgnoreFiles ) - { - std::vector<std::string> ignoreFilesRegexString; - cmSystemTools::ExpandListArgument(cpackIgnoreFiles, - ignoreFilesRegexString); - std::vector<std::string>::iterator it; - for ( it = ignoreFilesRegexString.begin(); - it != ignoreFilesRegexString.end(); - ++it ) - { - cmCPackLogger(cmCPackLog::LOG_VERBOSE, - "Create ignore files regex for: " << it->c_str() << std::endl); - ignoreFilesRegex.push_back(it->c_str()); - } - } this->CleanTemporaryDirectory(); const char* tempInstallDirectory = this->GetOption("CPACK_TEMPORARY_INSTALL_DIRECTORY"); @@ -178,6 +162,7 @@ int cmCPackGenericGenerator::InstallProject() << std::endl); return 0; } + bool movable = true; if ( movable ) { @@ -193,6 +178,83 @@ int cmCPackGenericGenerator::InstallProject() // If the CPackConfig file sets CPACK_INSTALL_COMMANDS then run them // as listed + if ( !this->InstallProjectViaInstallCommands( + movable, tempInstallDirectory) ) + { + return 0; + } + + // If the CPackConfig file sets CPACK_INSTALLED_DIRECTORIES + // then glob it and copy it to CPACK_TEMPORARY_DIRECTORY + // This is used in Source packageing + if ( !this->InstallProjectViaInstalledDirectories( + movable, tempInstallDirectory) ) + { + return 0; + } + + + // If the project is a CMAKE project then run pre-install + // and then read the cmake_install script to run it + if ( !this->InstallProjectViaInstallCMakeProjects( + movable, tempInstallDirectory) ) + { + return 0; + } + + if ( !movable ) + { + cmSystemTools::PutEnv("DESTDIR="); + } + + const char* stripExecutable = this->GetOption("CPACK_STRIP_COMMAND"); + const char* stripFiles + = this->GetOption("CPACK_STRIP_FILES"); + if ( stripFiles && *stripFiles && stripExecutable && *stripExecutable ) + { + cmCPackLogger(cmCPackLog::LOG_OUTPUT, "- Strip files" << std::endl); + std::vector<std::string> stripFilesVector; + cmSystemTools::ExpandListArgument(stripFiles, + stripFilesVector); + std::vector<std::string>::iterator it; + for ( it = stripFilesVector.begin(); + it != stripFilesVector.end(); + ++it ) + { + std::string fileName = tempInstallDirectory; + fileName += "/" + *it; + cmCPackLogger(cmCPackLog::LOG_VERBOSE, + " Strip file: " << fileName.c_str() + << std::endl); + std::string stripCommand = stripExecutable; + stripCommand += " \""; + stripCommand += fileName + "\""; + int retVal = 1; + std::string output; + bool resB = + cmSystemTools::RunSingleCommand(stripCommand.c_str(), &output, + &retVal, 0, + this->GeneratorVerbose, 0); + if ( !resB || retVal ) + { + cmCPackLogger(cmCPackLog::LOG_ERROR, + "Problem running install command: " << stripCommand.c_str() + << std::endl + << "Error was: \"" << output.c_str() << "\"" + << std::endl); + return 0; + } + } + } + return res; +} + +//---------------------------------------------------------------------- +int cmCPackGenericGenerator::InstallProjectViaInstallCommands( + bool movable, const char* tempInstallDirectory) +{ + (void)movable; + (void)tempInstallDirectory; const char* installCommands = this->GetOption("CPACK_INSTALL_COMMANDS"); if ( installCommands && *installCommands ) { @@ -221,15 +283,36 @@ int cmCPackGenericGenerator::InstallProject() "Problem running install command: " << it->c_str() << std::endl << "Please check " << tmpFile.c_str() << " for errors" << std::endl); - res = 0; - break; + return 0; } } } + return 1; +} - // If the CPackConfig file sets CPACK_INSTALLED_DIRECTORIES - // then glob it and copy it to CPACK_TEMPORARY_DIRECTORY - // This is used in Source packageing +//---------------------------------------------------------------------- +int cmCPackGenericGenerator::InstallProjectViaInstalledDirectories( + bool movable, const char* tempInstallDirectory) +{ + (void)movable; + (void)tempInstallDirectory; + std::vector<cmsys::RegularExpression> ignoreFilesRegex; + const char* cpackIgnoreFiles = this->GetOption("CPACK_IGNORE_FILES"); + if ( cpackIgnoreFiles ) + { + std::vector<std::string> ignoreFilesRegexString; + cmSystemTools::ExpandListArgument(cpackIgnoreFiles, + ignoreFilesRegexString); + std::vector<std::string>::iterator it; + for ( it = ignoreFilesRegexString.begin(); + it != ignoreFilesRegexString.end(); + ++it ) + { + cmCPackLogger(cmCPackLog::LOG_VERBOSE, + "Create ignore files regex for: " << it->c_str() << std::endl); + ignoreFilesRegex.push_back(it->c_str()); + } + } const char* installDirectories = this->GetOption("CPACK_INSTALLED_DIRECTORIES"); if ( installDirectories && *installDirectories ) @@ -304,9 +387,13 @@ int cmCPackGenericGenerator::InstallProject() } } } + return 1; +} - // If the project is a CMAKE project then run pre-install - // and then read the cmake_install script to run it +//---------------------------------------------------------------------- +int cmCPackGenericGenerator::InstallProjectViaInstallCMakeProjects( + bool movable, const char* tempInstallDirectory) +{ const char* cmakeProjects = this->GetOption("CPACK_INSTALL_CMAKE_PROJECTS"); const char* cmakeGenerator @@ -434,96 +521,14 @@ int cmCPackGenericGenerator::InstallProject() installComponent.c_str()); } - res = mf->ReadListFile(0, installFile.c_str()); - if ( cmSystemTools::GetErrorOccuredFlag() ) - { - res = 0; - } - } - } - - // ????? - const char* binaryDirectories = this->GetOption("CPACK_BINARY_DIR"); - if ( binaryDirectories && !cmakeProjects ) - { - std::vector<std::string> binaryDirectoriesVector; - cmSystemTools::ExpandListArgument(binaryDirectories, - binaryDirectoriesVector); - std::vector<std::string>::iterator it; - for ( it = binaryDirectoriesVector.begin(); - it != binaryDirectoriesVector.end(); - ++it ) - { - std::string installFile = it->c_str(); - installFile += "/cmake_install.cmake"; - cmake cm; - cmGlobalGenerator gg; - gg.SetCMakeInstance(&cm); - std::auto_ptr<cmLocalGenerator> lg(gg.CreateLocalGenerator()); - lg->SetGlobalGenerator(&gg); - cmMakefile *mf = lg->GetMakefile(); - if ( movable ) - { - mf->AddDefinition("CMAKE_INSTALL_PREFIX", tempInstallDirectory); - } - const char* buildConfig = this->GetOption("CPACK_BUILD_CONFIG"); - if ( buildConfig && *buildConfig ) - { - mf->AddDefinition("BUILD_TYPE", buildConfig); - } - - res = mf->ReadListFile(0, installFile.c_str()); - if ( cmSystemTools::GetErrorOccuredFlag() ) - { - res = 0; - } - } - } - if ( !movable ) - { - cmSystemTools::PutEnv("DESTDIR="); - } - - const char* stripExecutable = this->GetOption("CPACK_STRIP_COMMAND"); - const char* stripFiles - = this->GetOption("CPACK_STRIP_FILES"); - if ( stripFiles && *stripFiles && stripExecutable && *stripExecutable ) - { - cmCPackLogger(cmCPackLog::LOG_OUTPUT, "- Strip files" << std::endl); - std::vector<std::string> stripFilesVector; - cmSystemTools::ExpandListArgument(stripFiles, - stripFilesVector); - std::vector<std::string>::iterator it; - for ( it = stripFilesVector.begin(); - it != stripFilesVector.end(); - ++it ) - { - std::string fileName = tempInstallDirectory; - fileName += "/" + *it; - cmCPackLogger(cmCPackLog::LOG_VERBOSE, - " Strip file: " << fileName.c_str() - << std::endl); - std::string stripCommand = stripExecutable; - stripCommand += " \""; - stripCommand += fileName + "\""; - int retVal = 1; - std::string output; - bool resB = - cmSystemTools::RunSingleCommand(stripCommand.c_str(), &output, - &retVal, 0, - this->GeneratorVerbose, 0); - if ( !resB || retVal ) + int res = mf->ReadListFile(0, installFile.c_str()); + if ( cmSystemTools::GetErrorOccuredFlag() || !res ) { - cmCPackLogger(cmCPackLog::LOG_ERROR, - "Problem running install command: " << stripCommand.c_str() - << std::endl - << "Error was: \"" << output.c_str() << "\"" - << std::endl); return 0; } } } - return res; + return 1; } //---------------------------------------------------------------------- @@ -557,10 +562,32 @@ void cmCPackGenericGenerator::SetOption(const char* op, const char* value) //---------------------------------------------------------------------- int cmCPackGenericGenerator::ProcessGenerator() { + cmCPackLogger(cmCPackLog::LOG_OUTPUT, + "Create package using " << this->Name.c_str() << std::endl); + if ( !this->PrepareNames() ) { return 0; } + if ( cmSystemTools::IsOn( + this->GetOption("CPACK_REMOVE_TOPLEVEL_DIRECTORY")) ) + { + const char* toplevelDirectory + = this->GetOption("CPACK_TOPLEVEL_DIRECTORY"); + if ( cmSystemTools::FileExists(toplevelDirectory) ) + { + cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Remove toplevel directory: " + << toplevelDirectory << std::endl); + if ( !cmSystemTools::RemoveADirectory(toplevelDirectory) ) + { + cmCPackLogger(cmCPackLog::LOG_ERROR, + "Problem removing toplevel directory: " + << toplevelDirectory + << std::endl); + return 0; + } + } + } if ( !this->InstallProject() ) { return 0; @@ -668,7 +695,7 @@ int cmCPackGenericGenerator::FindRunningCMake(const char* arg0) { failures.push_back(this->CPackSelf); cmOStringStream msg; - msg << "CTEST can not find the command line program ctest.\n"; + msg << "CPack can not find the command line program ctest.\n"; msg << " argv[0] = \"" << arg0 << "\"\n"; msg << " Attempted paths:\n"; std::vector<cmStdString>::iterator i; @@ -676,7 +703,9 @@ int cmCPackGenericGenerator::FindRunningCMake(const char* arg0) { msg << " \"" << i->c_str() << "\"\n"; } - cmSystemTools::Error(msg.str().c_str()); + cmCPackLogger(cmCPackLog::LOG_ERROR, msg.str().c_str() + << std::endl); + return 0; } std::string dir; std::string file; @@ -708,7 +737,7 @@ int cmCPackGenericGenerator::FindRunningCMake(const char* arg0) { failures.push_back(this->CMakeSelf); cmOStringStream msg; - msg << "CTEST can not find the command line program cmake.\n"; + msg << "CPack can not find the command line program cmake.\n"; msg << " argv[0] = \"" << arg0 << "\"\n"; msg << " Attempted paths:\n"; std::vector<cmStdString>::iterator i; @@ -716,7 +745,9 @@ int cmCPackGenericGenerator::FindRunningCMake(const char* arg0) { msg << " \"" << i->c_str() << "\"\n"; } - cmSystemTools::Error(msg.str().c_str()); + cmCPackLogger(cmCPackLog::LOG_ERROR, msg.str().c_str() + << std::endl); + return 0; } } // do CMAKE_ROOT, look for the environment variable first @@ -792,10 +823,12 @@ int cmCPackGenericGenerator::FindRunningCMake(const char* arg0) if (!cmSystemTools::FileExists(modules.c_str())) { // couldn't find modules - cmSystemTools::Error("Could not find CMAKE_ROOT !!!\n" - "CMake has most likely not been installed correctly.\n" - "Modules directory not found in\n", - cMakeRoot.c_str()); + cmCPackLogger(cmCPackLog::LOG_ERROR, + "Could not find CMAKE_ROOT !!!" << std::endl + << "CMake has most likely not been installed correctly." << std::endl + <<"Modules directory not found in" << std::endl + << cMakeRoot.c_str() + << std::endl); return 0; } this->CMakeRoot = cMakeRoot; diff --git a/Source/CPack/cmCPackGenericGenerator.h b/Source/CPack/cmCPackGenericGenerator.h index 87c486d425..a5a0ef7f21 100644 --- a/Source/CPack/cmCPackGenericGenerator.h +++ b/Source/CPack/cmCPackGenericGenerator.h @@ -106,6 +106,15 @@ protected: virtual bool ConfigureString(const std::string& input, std::string& output); virtual int InitializeInternal(); + + //! Run install commands if specified + virtual int InstallProjectViaInstallCommands( + bool movable, const char* tempInstallDirectory); + virtual int InstallProjectViaInstalledDirectories( + bool movable, const char* tempInstallDirectory); + virtual int InstallProjectViaInstallCMakeProjects( + bool movable, const char* tempInstallDirectory); + bool GeneratorVerbose; std::string Name; diff --git a/Source/CPack/cpack.cxx b/Source/CPack/cpack.cxx index 49f6a70105..90421f9935 100644 --- a/Source/CPack/cpack.cxx +++ b/Source/CPack/cpack.cxx @@ -221,7 +221,7 @@ int main (int argc, char *argv[]) cmGlobalGenerator cmgg; cmgg.SetCMakeInstance(&cminst); cmLocalGenerator* cmlg = cmgg.CreateLocalGenerator(); - cmMakefile* mf = cmlg->GetMakefile(); + cmMakefile* globalMF = cmlg->GetMakefile(); bool cpackConfigFileSpecified = true; if ( cpackConfigFile.empty() ) @@ -247,7 +247,10 @@ int main (int argc, char *argv[]) { cpackConfigFile = cmSystemTools::CollapseFullPath(cpackConfigFile.c_str()); - if ( !mf->ReadListFile(0, cpackConfigFile.c_str()) ) + cmCPack_Log(&log, cmCPackLog::LOG_VERBOSE, + "Read CPack configuration file: " << cpackConfigFile.c_str() + << std::endl); + if ( !globalMF->ReadListFile(0, cpackConfigFile.c_str()) ) { cmCPack_Log(&log, cmCPackLog::LOG_ERROR, "Problem reding CPack config file: \"" @@ -265,44 +268,60 @@ int main (int argc, char *argv[]) if ( !generator.empty() ) { - mf->AddDefinition("CPACK_GENERATOR", generator.c_str()); + globalMF->AddDefinition("CPACK_GENERATOR", generator.c_str()); } if ( !cpackProjectName.empty() ) { - mf->AddDefinition("CPACK_PACKAGE_NAME", cpackProjectName.c_str()); + globalMF->AddDefinition("CPACK_PACKAGE_NAME", cpackProjectName.c_str()); } if ( !cpackProjectVersion.empty() ) { - mf->AddDefinition("CPACK_PACKAGE_VERSION", cpackProjectVersion.c_str()); + globalMF->AddDefinition("CPACK_PACKAGE_VERSION", + cpackProjectVersion.c_str()); } if ( !cpackProjectVendor.empty() ) { - mf->AddDefinition("CPACK_PACKAGE_VENDOR", cpackProjectVendor.c_str()); + globalMF->AddDefinition("CPACK_PACKAGE_VENDOR", + cpackProjectVendor.c_str()); } if ( !cpackProjectDirectory.empty() ) { - mf->AddDefinition("CPACK_PACKAGE_DIRECTORY", + globalMF->AddDefinition("CPACK_PACKAGE_DIRECTORY", cpackProjectDirectory.c_str()); } if ( !cpackBuildConfig.empty() ) { - mf->AddDefinition("CPACK_BUILD_CONFIG", cpackBuildConfig.c_str()); + globalMF->AddDefinition("CPACK_BUILD_CONFIG", cpackBuildConfig.c_str()); } cpackDefinitions::MapType::iterator cdit; for ( cdit = definitions.Map.begin(); cdit != definitions.Map.end(); ++cdit ) { - mf->AddDefinition(cdit->first.c_str(), cdit->second.c_str()); + globalMF->AddDefinition(cdit->first.c_str(), cdit->second.c_str()); } - const char* gen = mf->GetDefinition("CPACK_GENERATOR"); - if ( !gen ) + const char* genList = globalMF->GetDefinition("CPACK_GENERATOR"); + if ( !genList ) { cmCPack_Log(&log, cmCPackLog::LOG_ERROR, "CPack generator not specified" << std::endl); parsed = 0; } + std::vector<std::string> generatorsVector; + cmSystemTools::ExpandListArgument(genList, + generatorsVector); + std::vector<std::string>::iterator it; + for ( it = generatorsVector.begin(); + it != generatorsVector.end(); + ++it ) + { + const char* gen = it->c_str(); + cmMakefile newMF(*globalMF); + cmMakefile* mf = &newMF; + { + cmCPack_Log(&log, cmCPackLog::LOG_VERBOSE, + "Specified generator: " << gen << std::endl); if ( parsed && !mf->GetDefinition("CPACK_PACKAGE_NAME") ) { cmCPack_Log(&log, cmCPackLog::LOG_ERROR, @@ -316,7 +335,8 @@ int main (int argc, char *argv[]) { cmCPack_Log(&log, cmCPackLog::LOG_ERROR, "CPack project version not specified" << std::endl - << "Specify CPACK_PACKAGE_VERSION, or CPACK_PACKAGE_VERSION_MAJOR, " + << "Specify CPACK_PACKAGE_VERSION, or " + "CPACK_PACKAGE_VERSION_MAJOR, " "CPACK_PACKAGE_VERSION_MINOR, and CPACK_PACKAGE_VERSION_PATCH." << std::endl); parsed = 0; @@ -343,9 +363,10 @@ int main (int argc, char *argv[]) !mf->GetDefinition("CPACK_INSTALL_CMAKE_PROJECTS") ) { cmCPack_Log(&log, cmCPackLog::LOG_ERROR, - "Please specify build tree of the project that uses CMake using " - " CPACK_INSTALL_CMAKE_PROJECTS, specify CPACK_INSTALL_COMMANDS, or " - "specify CPACK_INSTALLED_DIRECTORIES." + "Please specify build tree of the project that uses CMake " + "using CPACK_INSTALL_CMAKE_PROJECTS, specify " + "CPACK_INSTALL_COMMANDS, or specify " + "CPACK_INSTALLED_DIRECTORIES." << std::endl); parsed = 0; } @@ -416,6 +437,8 @@ int main (int argc, char *argv[]) cmCPack_Log(&log, cmCPackLog::LOG_ERROR, "Error when generating package: " << projName << std::endl); return 1; + } + } } return 0; diff --git a/Source/CTest/cmCTestBuildHandler.cxx b/Source/CTest/cmCTestBuildHandler.cxx index 7136ad5a90..fc194aa921 100644 --- a/Source/CTest/cmCTestBuildHandler.cxx +++ b/Source/CTest/cmCTestBuildHandler.cxx @@ -724,7 +724,6 @@ void cmCTestBuildHandler::ProcessBuffer(const char* data, int length, size_t& tick, size_t tick_len, std::ofstream& ofs, t_BuildProcessingQueueType* queue) { -#undef cerr const std::string::size_type tick_line_len = 50; const char* ptr; for ( ptr = data; ptr < data+length; ptr ++ ) diff --git a/Source/CTest/cmCTestConfigureCommand.cxx b/Source/CTest/cmCTestConfigureCommand.cxx index 9a30fe8f98..ce2ff3c5ee 100644 --- a/Source/CTest/cmCTestConfigureCommand.cxx +++ b/Source/CTest/cmCTestConfigureCommand.cxx @@ -24,22 +24,26 @@ cmCTestGenericHandler* cmCTestConfigureCommand::InitializeHandler() if ( this->Values[ct_BUILD] ) { this->CTest->SetCTestConfiguration("BuildDirectory", - this->Values[ct_BUILD]); + cmSystemTools::CollapseFullPath( + this->Values[ct_BUILD]).c_str()); } else { this->CTest->SetCTestConfiguration("BuildDirectory", - this->Makefile->GetDefinition("CTEST_BINARY_DIRECTORY")); + cmSystemTools::CollapseFullPath( + this->Makefile->GetDefinition("CTEST_BINARY_DIRECTORY")).c_str()); } if ( this->Values[ct_SOURCE] ) { this->CTest->SetCTestConfiguration("SourceDirectory", - this->Values[ct_SOURCE]); + cmSystemTools::CollapseFullPath( + this->Values[ct_SOURCE]).c_str()); } else { this->CTest->SetCTestConfiguration("SourceDirectory", - this->Makefile->GetDefinition("CTEST_SOURCE_DIRECTORY")); + cmSystemTools::CollapseFullPath( + this->Makefile->GetDefinition("CTEST_SOURCE_DIRECTORY")).c_str()); } if ( this->CTest->GetCTestConfiguration("BuildDirectory").empty() ) { diff --git a/Source/CTest/cmCTestHandlerCommand.cxx b/Source/CTest/cmCTestHandlerCommand.cxx index 09fd82ac3f..2313569c6a 100644 --- a/Source/CTest/cmCTestHandlerCommand.cxx +++ b/Source/CTest/cmCTestHandlerCommand.cxx @@ -58,24 +58,28 @@ bool cmCTestHandlerCommand::InitialPass( if ( this->Values[ct_BUILD] ) { this->CTest->SetCTestConfiguration("BuildDirectory", - this->Values[ct_BUILD]); + cmSystemTools::CollapseFullPath( + this->Values[ct_BUILD]).c_str()); } else { this->CTest->SetCTestConfiguration("BuildDirectory", - this->Makefile->GetDefinition("CTEST_BINARY_DIRECTORY")); + cmSystemTools::CollapseFullPath( + this->Makefile->GetDefinition("CTEST_BINARY_DIRECTORY")).c_str()); } if ( this->Values[ct_SOURCE] ) { cmCTestLog(this->CTest, DEBUG, "Set source directory to: " << this->Values[ct_SOURCE] << std::endl); this->CTest->SetCTestConfiguration("SourceDirectory", - this->Values[ct_SOURCE]); + cmSystemTools::CollapseFullPath( + this->Values[ct_SOURCE]).c_str()); } else { this->CTest->SetCTestConfiguration("SourceDirectory", - this->Makefile->GetDefinition("CTEST_SOURCE_DIRECTORY")); + cmSystemTools::CollapseFullPath( + this->Makefile->GetDefinition("CTEST_SOURCE_DIRECTORY")).c_str()); } if ( this->Values[ct_SUBMIT_INDEX] ) { diff --git a/Source/CTest/cmCTestScriptHandler.cxx b/Source/CTest/cmCTestScriptHandler.cxx index 72788c00d9..5b73e2ac00 100644 --- a/Source/CTest/cmCTestScriptHandler.cxx +++ b/Source/CTest/cmCTestScriptHandler.cxx @@ -699,6 +699,7 @@ int cmCTestScriptHandler::PerformExtraUpdates() if (!res || retVal != 0) { cmSystemTools::Error("Unable to perform extra updates:\n", + it->c_str(), "\nWith output:\n", output.c_str()); return 0; } diff --git a/Source/CTest/cmCTestStartCommand.cxx b/Source/CTest/cmCTestStartCommand.cxx index aa77c7548c..30aff0b8ab 100644 --- a/Source/CTest/cmCTestStartCommand.cxx +++ b/Source/CTest/cmCTestStartCommand.cxx @@ -77,8 +77,10 @@ bool cmCTestStartCommand::InitialPass( return false; } this->CTest->EmptyCTestConfiguration(); - this->CTest->SetCTestConfiguration("SourceDirectory", src_dir); - this->CTest->SetCTestConfiguration("BuildDirectory", bld_dir); + this->CTest->SetCTestConfiguration("SourceDirectory", + cmSystemTools::CollapseFullPath(src_dir).c_str()); + this->CTest->SetCTestConfiguration("BuildDirectory", + cmSystemTools::CollapseFullPath(bld_dir).c_str()); cmCTestLog(this->CTest, HANDLER_OUTPUT, "Run dashboard with model " << smodel << std::endl diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx index 5da776f29c..28cbc61f69 100644 --- a/Source/CTest/cmCTestTestHandler.cxx +++ b/Source/CTest/cmCTestTestHandler.cxx @@ -1655,6 +1655,7 @@ bool cmCTestTestHandler::SetTestsProperties( bool cmCTestTestHandler::AddTest(const std::vector<std::string>& args) { const std::string& testname = args[0]; + cmCTestLog(this->CTest, DEBUG, "Add test: " << args[0] << std::endl); if (this->UseExcludeRegExpFlag && this->UseExcludeRegExpFirst && this->ExcludeTestsRegularExpression.find(testname.c_str())) @@ -1706,6 +1707,9 @@ bool cmCTestTestHandler::AddTest(const std::vector<std::string>& args) test.Name = testname; test.Args = args; test.Directory = cmSystemTools::GetCurrentWorkingDirectory(); + cmCTestLog(this->CTest, DEBUG, "Set test directory: " + << test.Directory << std::endl); + test.IsInBasedOnREOptions = true; test.WillFail = false; if (this->UseIncludeRegExpFlag && diff --git a/Source/CTest/cmCTestUpdateCommand.cxx b/Source/CTest/cmCTestUpdateCommand.cxx index 2c116c04b9..913478ae05 100644 --- a/Source/CTest/cmCTestUpdateCommand.cxx +++ b/Source/CTest/cmCTestUpdateCommand.cxx @@ -24,12 +24,14 @@ cmCTestGenericHandler* cmCTestUpdateCommand::InitializeHandler() if ( this->Values[ct_SOURCE] ) { this->CTest->SetCTestConfiguration("SourceDirectory", - this->Values[ct_SOURCE]); + cmSystemTools::CollapseFullPath( + this->Values[ct_SOURCE]).c_str()); } else { this->CTest->SetCTestConfiguration("SourceDirectory", - this->Makefile->GetDefinition("CTEST_SOURCE_DIRECTORY")); + cmSystemTools::CollapseFullPath( + this->Makefile->GetDefinition("CTEST_SOURCE_DIRECTORY")).c_str()); } std::string source_dir = this->CTest->GetCTestConfiguration("SourceDirectory"); diff --git a/Source/WXDialog/CMakeLists.txt b/Source/WXDialog/CMakeLists.txt index 29b4fae5b7..3d4561da4e 100644 --- a/Source/WXDialog/CMakeLists.txt +++ b/Source/WXDialog/CMakeLists.txt @@ -9,35 +9,25 @@ ## License: wxWidgets License ##--------------------------------------------------------------------------- +# wxWindows -> wxWidgets Jan Woetzel 07/2006 +# tested with wx 2.6.3 with "multilib" build on Windows XP -#wxWidgets build related stuff -SET(WXW_USE_DEBUG OFF) -SET(WXW_USE_UNICODE OFF) -SET(WXW_USE_SHARED OFF) -SET(WXW_USE_UNIV OFF) -SET(WXW_USE_MONO OFF) -SET(WXW_FILE_VERSION "26") -SET(WXW_VERSION "2.6") - -#CMake Options +# CMake Options SET(CMAKE_VERBOSE_MAKEFILE TRUE) -IF(WIN32) - INCLUDE (${CMAKE_SOURCE_DIR}/Source/WXDialog/bin/FindwxW.cmake) -ELSE(WIN32) - INCLUDE (${CMAKE_SOURCE_DIR}/Source/WXDialog/bin/FindwxWin.cmake) - - # sync flags - SET(WXWIDGETS_FOUND ${WXWINDOWS_FOUND}) - SET(WXWIDGETS_INCLUDE_DIR ${WXWINDOWS_INCLUDE_DIR}) - SET(WXWIDGETS_LINK_DIRECTORIES ${WXWINDOWS_LINK_DIRECTORIES}) - SET(WXWIDGETS_LIBRARIES ${WXWINDOWS_LIBRARIES}) -ENDIF(WIN32) +# suppress wx header warnings? +#SET(HAVE_ISYSTEM 1) -# Old find script +# in addition to wx std libs we need +SET( wxWidgets_USE_LIBS + std + html adv xml xrc ) +FIND_PACKAGE(wxWidgets REQUIRED) +#INCLUDE(${CMAKE_ROOT}/Modules/FindwxWidgets.cmake) -## Start using wx stuff when it is fully found and set -IF(WXWIDGETS_FOUND) +# Start using wx stuff when it is fully found and set +IF(wxWidgets_FOUND) + INCLUDE( ${wxWidgets_USE_FILE} ) SET (CMAKE_SRCS CMakeSetupFrame.cpp @@ -59,24 +49,32 @@ IF(WXWIDGETS_FOUND) CommandLineInfo.h ) # include .rc when windows - IF(WIN32) - SET ( CMAKE_SRCS - ${CMAKE_SRCS} - CMakeSetup.rc ) + SET ( CMAKE_SRCS ${CMAKE_SRCS} CMakeSetup.rc ) ENDIF(WIN32) INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/Source/WXDialog - ${WXWIDGETS_INCLUDE_DIR}) - LINK_DIRECTORIES( ${WXWIDGETS_LINK_DIRECTORIES} ${CMake_BINARY_DIR}/Source ${CMake_BINARY_DIR}/Source/kwsys ) + ${wxWidgets_INCLUDE_DIR} ) + LINK_DIRECTORIES( ${wxWidgets_LINK_DIRECTORIES} + ${CMake_BINARY_DIR}/Source + ${CMake_BINARY_DIR}/Source/kwsys ) + IF(APPLE) ADD_EXECUTABLE(WXDialog MACOSX_BUNDLE ${CMAKE_SRCS}) ELSE(APPLE) ADD_EXECUTABLE(WXDialog WIN32 ${CMAKE_SRCS}) ENDIF(APPLE) INSTALL_TARGETS(/bin WXDialog) - SET(CMAKE_CXX_FLAGS "${CMAKE_WX_CXX_FLAGS}") - SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D__WXDEBUG__ -DWXDEBUG=1") + + # not required on MSVS beause bound to _DEBUG, + # but other compiler may need it. + # However, the define prevents multiple build configurations + # in one build tree, + # e.g. MSVS supports Debug;Release + # TODO: shall we add the define or not - + # favor multi config or all compilers? (JW) + SET(CMAKE_CXX_FLAGS_DEBUG + "${CMAKE_CXX_FLAGS_DEBUG} -D__WXDEBUG__ -DWXDEBUG=1") IF(LINUX) ADD_DEFINITIONS( -DLINUX=1 ) @@ -84,13 +82,6 @@ IF(WXWIDGETS_FOUND) # if the checkbox view functionality is not desired, # exclude this part from the smple - SET(WXWIDGETS_LIBRARIES ${WXWIDGETS_LIBRARIES}) - TARGET_LINK_LIBRARIES(WXDialog ${WXWIDGETS_LIBRARIES} cmsys CMakeLib) - - # if UPX is found, make a target - - #INCLUDE (${CMAKE_SOURCE_DIR}/Source/WXDialog/bin/FindUPX.cmake) - #IF(UPX_FOUND) - #END(UPX_FOUND) + TARGET_LINK_LIBRARIES(WXDialog ${wxWidgets_LIBRARIES} cmsys CMakeLib) -ENDIF(WXWIDGETS_FOUND) +ENDIF(wxWidgets_FOUND) diff --git a/Source/WXDialog/bin/FindUPX.cmake b/Source/WXDialog/bin/FindUPX.cmake index 762384199e..438e6b4afb 100644 --- a/Source/WXDialog/bin/FindUPX.cmake +++ b/Source/WXDialog/bin/FindUPX.cmake @@ -5,12 +5,9 @@ # UPX_FOUND Is set to 1 when upx is found FIND_PATH(UPX_PROGRAM_PATH upx.exe - "c:\Program Files\upx" - "d:\Program Files\upx" - "e:\Program Files\upx" - "f:\Program Files\upx" - "g:\Program Files\upx" - "h:\Program Files\upx" + ${UPX_DIR} + $ENV{UPX_DIR} + "$ENV{ProgramFiles}/upx" ) # when found, note this as target diff --git a/Source/WXDialog/bin/FindwxW.cmake b/Source/WXDialog/bin/FindwxW.cmake index 230bba8369..f88eb0e3f9 100644 --- a/Source/WXDialog/bin/FindwxW.cmake +++ b/Source/WXDialog/bin/FindwxW.cmake @@ -1,3 +1,6 @@ + +MESSAGE("${CMAKE_CURRENT_FILE} is deprecated, please use FindwxWidgets.cmake instead.") + # # FindwxW.cmake # v1.01 2005-05-27 @@ -14,6 +17,7 @@ # WXWIDGETS_INCLUDE_DIR = all include path of wxWindows # WXWIDGETS_DEFINITIONS = all flags of wxWindows + # NOTE: This module REQUIRES that an environment variable named WXWIN # be set to the base wxWidgets installation directory. # Under Unix, you must also set and environment variable named WXWINCFG diff --git a/Source/WXDialog/bin/FindwxWin.cmake b/Source/WXDialog/bin/FindwxWin.cmake index 699e7e1782..7278dca113 100644 --- a/Source/WXDialog/bin/FindwxWin.cmake +++ b/Source/WXDialog/bin/FindwxWin.cmake @@ -1,3 +1,8 @@ + + +MESSAGE("${CMAKE_CURRENT_FILE} is deprecated, please use FindwxWidgets.cmake instead.") + + ##--------------------------------------------------------------------------- ## $RCSfile$ ## $Source$ diff --git a/Source/WXDialog/bin/UsewxW.cmake b/Source/WXDialog/bin/UsewxW.cmake index e550e89b82..702ab9d99b 100644 --- a/Source/WXDialog/bin/UsewxW.cmake +++ b/Source/WXDialog/bin/UsewxW.cmake @@ -1,3 +1,7 @@ + +MESSAGE("${CMAKE_CURRENT_FILE} is deprecated, please use FindwxWidgets.cmake instead.") + + # # UsewxW.cmake # v1.0 2005-05-27 diff --git a/Source/cmBuildCommand.cxx b/Source/cmBuildCommand.cxx index 405b463d53..fd3760c5ef 100644 --- a/Source/cmBuildCommand.cxx +++ b/Source/cmBuildCommand.cxx @@ -31,10 +31,16 @@ bool cmBuildCommand::InitialPass(std::vector<std::string> const& args) const char* cacheValue = this->Makefile->GetDefinition(define); std::string makeprogram = args[1]; + std::string configType = "Release"; + const char* cfg = getenv("CMAKE_CONFIG_TYPE"); + if ( cfg ) + { + configType = cfg; + } std::string makecommand = this->Makefile->GetLocalGenerator() ->GetGlobalGenerator()->GenerateBuildCommand (makeprogram.c_str(), this->Makefile->GetProjectName(), 0, - 0, "Release", true, false); + 0, configType.c_str(), true, false); if(cacheValue) { diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx index e7fc7e0495..b5e79a461a 100644 --- a/Source/cmCTest.cxx +++ b/Source/cmCTest.cxx @@ -289,6 +289,10 @@ int cmCTest::Initialize(const char* binary_dir, bool new_tag, { this->BlockTestErrorDiagnostics(); } + else + { + cmSystemTools::PutEnv("CTEST_INTERACTIVE_DEBUG_MODE=1"); + } this->BinaryDir = binary_dir; cmSystemTools::ConvertToUnixSlashes(this->BinaryDir); @@ -1336,6 +1340,12 @@ int cmCTest::Run(std::vector<std::string>const& args, std::string* output) i++; this->ConfigType = args[i]; cmSystemTools::ReplaceString(this->ConfigType, ".\\", ""); + if ( !this->ConfigType.empty() ) + { + std::string confTypeEnv + = "CMAKE_CONFIG_TYPE=" + this->ConfigType; + cmSystemTools::PutEnv(confTypeEnv.c_str()); + } } if(this->CheckArgument(arg, "--debug")) @@ -2050,8 +2060,11 @@ void cmCTest::PopulateCustomInteger(cmMakefile* mf, const char* def, int& val) std::string cmCTest::GetShortPathToFile(const char* cfname) { const std::string& sourceDir - = this->GetCTestConfiguration("SourceDirectory"); - const std::string& buildDir = this->GetCTestConfiguration("BuildDirectory"); + = cmSystemTools::CollapseFullPath( + this->GetCTestConfiguration("SourceDirectory").c_str()); + const std::string& buildDir + = cmSystemTools::CollapseFullPath( + this->GetCTestConfiguration("BuildDirectory").c_str()); std::string fname = cmSystemTools::CollapseFullPath(cfname); // Find relative paths to both directories diff --git a/Source/cmFindBase.cxx b/Source/cmFindBase.cxx index e2fc963046..605a790a35 100644 --- a/Source/cmFindBase.cxx +++ b/Source/cmFindBase.cxx @@ -19,6 +19,7 @@ cmFindBase::cmFindBase() { this->AlreadyInCache = false; + this->AlreadyInCacheWithoutMetaInfo = false; this->NoDefaultPath = false; this->NoCMakePath = false; this->NoCMakeEnvironmentPath = false; @@ -674,18 +675,27 @@ void cmFindBase::PrintFindStuff() bool cmFindBase::CheckForVariableInCache() { - const char* cacheValue - = this->Makefile->GetDefinition(this->VariableName.c_str()); - if(cacheValue && !cmSystemTools::IsNOTFOUND(cacheValue)) - { - return true; - } - if(cacheValue) + if(const char* cacheValue = + this->Makefile->GetDefinition(this->VariableName.c_str())) { cmCacheManager::CacheIterator it = this->Makefile->GetCacheManager()-> GetCacheIterator(this->VariableName.c_str()); - if(!it.IsAtEnd()) + bool found = !cmSystemTools::IsNOTFOUND(cacheValue); + bool cached = !it.IsAtEnd(); + if(found) + { + // If the user specifies the entry on the command line without a + // type we should add the type and docstring but keep the + // original value. Tell the subclass implementations to do + // this. + if(cached && it.GetType() == cmCacheManager::UNINITIALIZED) + { + this->AlreadyInCacheWithoutMetaInfo = true; + } + return true; + } + else if(cached) { const char* hs = it.GetProperty("HELPSTRING"); this->VariableDocumentation = hs?hs:"(none)"; diff --git a/Source/cmFindBase.h b/Source/cmFindBase.h index 60c8853e88..e7084a441a 100644 --- a/Source/cmFindBase.h +++ b/Source/cmFindBase.h @@ -67,6 +67,7 @@ protected: cmStdString EnvironmentPath; // LIB,INCLUDE bool AlreadyInCache; + bool AlreadyInCacheWithoutMetaInfo; bool NoDefaultPath; bool NoCMakePath; bool NoCMakeEnvironmentPath; diff --git a/Source/cmFindLibraryCommand.cxx b/Source/cmFindLibraryCommand.cxx index 1cac1202af..24d5b044ed 100644 --- a/Source/cmFindLibraryCommand.cxx +++ b/Source/cmFindLibraryCommand.cxx @@ -52,6 +52,15 @@ bool cmFindLibraryCommand::InitialPass(std::vector<std::string> const& argsIn) } if(this->AlreadyInCache) { + // If the user specifies the entry on the command line without a + // type we should add the type and docstring but keep the original + // value. + if(this->AlreadyInCacheWithoutMetaInfo) + { + this->Makefile->AddCacheDefinition(this->VariableName.c_str(), "", + this->VariableDocumentation.c_str(), + cmCacheManager::FILEPATH); + } return true; } // add special 64 bit paths if this is a 64 bit compile. diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx index 0179626543..e173d4784a 100644 --- a/Source/cmFindPackageCommand.cxx +++ b/Source/cmFindPackageCommand.cxx @@ -56,6 +56,9 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args) this->Name = args[0]; + // Build a list of required components. + std::string components; + const char* components_sep = ""; bool quiet = false; bool required = false; if(args.size() > 1) @@ -74,11 +77,32 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args) } else if(args[i] == "REQUIRED") { + // The package is required. required = true; - while (++i < args.size() && args[i] != "QUIET") + + // Look for a list of required components. + while(++i < args.size()) + { + // Stop looking when a known keyword argument is + // encountered. + if((args[i] == "QUIET") || + (args[i] == "REQUIRED")) + { + --i; + break; + } + else { + // Set a variable telling the find script this component + // is required. std::string req_var = Name + "_FIND_REQUIRED_" + args[i]; this->Makefile->AddDefinition(req_var.c_str(), "1"); + + // Append to the list of required components. + components += components_sep; + components += args[i]; + components_sep = ";"; + } } } else @@ -89,6 +113,10 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args) return false; } } + + // Store the list of components. + std::string components_var = Name + "_FIND_COMPONENTS"; + this->Makefile->AddDefinition(components_var.c_str(), components.c_str()); } // See if there is a Find<name>.cmake module. diff --git a/Source/cmFindPathCommand.cxx b/Source/cmFindPathCommand.cxx index 33c590888d..ac8138c487 100644 --- a/Source/cmFindPathCommand.cxx +++ b/Source/cmFindPathCommand.cxx @@ -67,6 +67,18 @@ bool cmFindPathCommand::InitialPass(std::vector<std::string> const& argsIn) } if(this->AlreadyInCache) { + // If the user specifies the entry on the command line without a + // type we should add the type and docstring but keep the original + // value. + if(this->AlreadyInCacheWithoutMetaInfo) + { + this->Makefile->AddCacheDefinition( + this->VariableName.c_str(), "", + this->VariableDocumentation.c_str(), + (this->IncludeFileInPath ? + cmCacheManager::FILEPATH :cmCacheManager::PATH) + ); + } return true; } std::string ff = this->Makefile->GetSafeDefinition("CMAKE_FIND_FRAMEWORK"); diff --git a/Source/cmFindProgramCommand.cxx b/Source/cmFindProgramCommand.cxx index 6a4634b7ac..0806055190 100644 --- a/Source/cmFindProgramCommand.cxx +++ b/Source/cmFindProgramCommand.cxx @@ -51,6 +51,15 @@ bool cmFindProgramCommand::InitialPass(std::vector<std::string> const& argsIn) } if(this->AlreadyInCache) { + // If the user specifies the entry on the command line without a + // type we should add the type and docstring but keep the original + // value. + if(this->AlreadyInCacheWithoutMetaInfo) + { + this->Makefile->AddCacheDefinition(this->VariableName.c_str(), "", + this->VariableDocumentation.c_str(), + cmCacheManager::FILEPATH); + } return true; } diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx index df34fa3f73..0a2226f7a0 100644 --- a/Source/cmGlobalUnixMakefileGenerator3.cxx +++ b/Source/cmGlobalUnixMakefileGenerator3.cxx @@ -29,8 +29,6 @@ cmGlobalUnixMakefileGenerator3::cmGlobalUnixMakefileGenerator3() this->ForceUnixPaths = true; this->FindMakeProgramFile = "CMakeUnixFindMake.cmake"; this->ToolSupportsColor = true; - this->NumberOfSourceFiles = 0; - this->NumberOfSourceFilesWritten = 0; #ifdef _WIN32 this->UseLinkScript = false; #else @@ -118,86 +116,43 @@ cmGlobalUnixMakefileGenerator3 this->MultipleOutputPairs.insert(p); } -//---------------------------------------------------------------------------- -int cmGlobalUnixMakefileGenerator3::ShouldAddProgressRule() -{ - // add progress to 100 source files - if (this->NumberOfSourceFiles && - (((this->NumberOfSourceFilesWritten + 1)*100)/this->NumberOfSourceFiles) - -(this->NumberOfSourceFilesWritten*100)/this->NumberOfSourceFiles) - { - this->NumberOfSourceFilesWritten++; - return (this->NumberOfSourceFilesWritten*100)/this->NumberOfSourceFiles; - } - this->NumberOfSourceFilesWritten++; - return 0; -} - -int cmGlobalUnixMakefileGenerator3:: -GetNumberOfCompilableSourceFilesForTarget(cmTarget &tgt) -{ - std::map<cmStdString, int >::iterator tgtI = - this->TargetSourceFileCount.find(tgt.GetName()); - if (tgtI != this->TargetSourceFileCount.end()) - { - return tgtI->second; - } - - int result = 0; - - if((tgt.GetType() == cmTarget::EXECUTABLE) || - (tgt.GetType() == cmTarget::STATIC_LIBRARY) || - (tgt.GetType() == cmTarget::SHARED_LIBRARY) || - (tgt.GetType() == cmTarget::MODULE_LIBRARY) ) - { - std::vector<cmSourceFile*>& sources = tgt.GetSourceFiles(); - for(std::vector<cmSourceFile*>::iterator source = sources.begin(); - source != sources.end(); ++source) - { - if(!(*source)->GetPropertyAsBool("HEADER_FILE_ONLY") && - !(*source)->GetCustomCommand()) - { - if(!this->IgnoreFile((*source)->GetSourceExtension().c_str())) - { - const char* lang = - static_cast<cmLocalUnixMakefileGenerator3 *> - (tgt.GetMakefile()->GetLocalGenerator()) - ->GetSourceFileLanguage(**source); - if(lang) - { - result++; - } - } - } - } - } - this->TargetSourceFileCount[tgt.GetName()] = result; - return result; -} - //---------------------------------------------------------------------------- void cmGlobalUnixMakefileGenerator3::Generate() { + // first do superclass method + this->cmGlobalGenerator::Generate(); + // initialize progress - this->NumberOfSourceFiles = 0; unsigned int i; + unsigned long total = 0; for (i = 0; i < this->LocalGenerators.size(); ++i) { - // for all of out targets - for (cmTargets::iterator l = - this->LocalGenerators[i]->GetMakefile()->GetTargets().begin(); - l != this->LocalGenerators[i]->GetMakefile()->GetTargets().end(); - l++) + cmLocalUnixMakefileGenerator3 *lg = + static_cast<cmLocalUnixMakefileGenerator3 *>(this->LocalGenerators[i]); + total += lg->GetNumberOfProgressActions(); + } + + // write each target's progress.make this loop is done twice. Bascially the + // Generate pass counts all the actions, the first loop below determines + // how many actions have progress updates for each target and writes to + // corrrect variable values for everything except the all targets. The + // second loop actually writes out correct values for the all targets as + // well. This is because the all targets require more information that is + // computed in the first loop. + unsigned long current = 0; + for (i = 0; i < this->LocalGenerators.size(); ++i) { - this->NumberOfSourceFiles += - this->GetNumberOfCompilableSourceFilesForTarget(l->second); + cmLocalUnixMakefileGenerator3 *lg = + static_cast<cmLocalUnixMakefileGenerator3 *>(this->LocalGenerators[i]); + lg->WriteProgressVariables(total,current); } + for (i = 0; i < this->LocalGenerators.size(); ++i) + { + cmLocalUnixMakefileGenerator3 *lg = + static_cast<cmLocalUnixMakefileGenerator3 *>(this->LocalGenerators[i]); + lg->WriteAllProgressVariable(); } - this->NumberOfSourceFilesWritten = 0; - - // first do superclass method - this->cmGlobalGenerator::Generate(); // write the main makefile this->WriteMainMakefile2(); @@ -869,7 +824,7 @@ cmGlobalUnixMakefileGenerator3 cmLocalGenerator::SHELL); // progCmd << " " - << this->GetTargetTotalNumberOfProgressFiles(t->second); + << this->GetTargetTotalNumberOfActions(t->second); commands.push_back(progCmd.str()); } std::string tmp = cmake::GetCMakeFilesDirectoryPostSlash(); @@ -940,7 +895,7 @@ cmGlobalUnixMakefileGenerator3 //---------------------------------------------------------------------------- int cmGlobalUnixMakefileGenerator3 -::GetTargetTotalNumberOfProgressFiles(cmTarget& target) +::GetTargetTotalNumberOfActions(cmTarget& target) { cmLocalUnixMakefileGenerator3 *lg = static_cast<cmLocalUnixMakefileGenerator3 *> @@ -951,12 +906,112 @@ int cmGlobalUnixMakefileGenerator3 std::vector<cmTarget *>::iterator i; for (i = depends.begin(); i != depends.end(); ++i) { - result += this->GetTargetTotalNumberOfProgressFiles(**i); + result += this->GetTargetTotalNumberOfActions(**i); } return result; } +unsigned long cmGlobalUnixMakefileGenerator3:: +GetNumberOfProgressActionsInAll(cmLocalUnixMakefileGenerator3 *lg) +{ + unsigned long result = 0; + + // for every target in the top level all + if (!lg->GetParent()) + { + // loop over the generators and targets + unsigned int i; + cmLocalUnixMakefileGenerator3 *lg3; + for (i = 0; i < this->LocalGenerators.size(); ++i) + { + lg3 = static_cast<cmLocalUnixMakefileGenerator3 *> + (this->LocalGenerators[i]); + // for each target Generate the rule files for each target. + cmTargets& targets = lg3->GetMakefile()->GetTargets(); + for(cmTargets::iterator t = targets.begin(); t != targets.end(); ++t) + { + if((t->second.GetType() == cmTarget::EXECUTABLE) || + (t->second.GetType() == cmTarget::STATIC_LIBRARY) || + (t->second.GetType() == cmTarget::SHARED_LIBRARY) || + (t->second.GetType() == cmTarget::MODULE_LIBRARY) || + (t->second.GetType() == cmTarget::UTILITY)) + { + if (t->second.IsInAll()) + { + std::vector<int> &progFiles = lg3->ProgressFiles[t->first]; + result += static_cast<unsigned long>(progFiles.size()); + } + } + } + } + } + else + { + std::deque<cmLocalUnixMakefileGenerator3 *> lg3Stack; + lg3Stack.push_back(lg); + std::vector<cmStdString> targetsInAll; + std::set<cmTarget *> targets; + while (lg3Stack.size()) + { + cmLocalUnixMakefileGenerator3 *lg3 = lg3Stack.front(); + lg3Stack.pop_front(); + for(cmTargets::iterator l = lg3->GetMakefile()->GetTargets().begin(); + l != lg3->GetMakefile()->GetTargets().end(); ++l) + { + if((l->second.GetType() == cmTarget::EXECUTABLE) || + (l->second.GetType() == cmTarget::STATIC_LIBRARY) || + (l->second.GetType() == cmTarget::SHARED_LIBRARY) || + (l->second.GetType() == cmTarget::MODULE_LIBRARY) || + (l->second.GetType() == cmTarget::UTILITY)) + { + // Add this to the list of depends rules in this directory. + if (l->second.IsInAll() && + targets.find(&l->second) == targets.end()) + { + std::deque<cmTarget *> activeTgts; + activeTgts.push_back(&(l->second)); + // trace depth of target dependencies + while (activeTgts.size()) + { + if (targets.find(activeTgts.front()) == targets.end()) + { + targets.insert(activeTgts.front()); + cmLocalUnixMakefileGenerator3 *lg4 = + static_cast<cmLocalUnixMakefileGenerator3 *> + (activeTgts.front()->GetMakefile()->GetLocalGenerator()); + std::vector<int> &progFiles2 = + lg4->ProgressFiles[activeTgts.front()->GetName()]; + result += static_cast<unsigned long>(progFiles2.size()); + std::vector<cmTarget *> deps2 = + this->GetTargetDepends(*activeTgts.front()); + for (std::vector<cmTarget *>::const_iterator di = + deps2.begin(); di != deps2.end(); ++di) + { + activeTgts.push_back(*di); + } + } + activeTgts.pop_front(); + } + } + } + } + + // The directory-level rule depends on the directory-level + // rules of the subdirectories. + for(std::vector<cmLocalGenerator*>::iterator sdi = + lg3->GetChildren().begin(); + sdi != lg3->GetChildren().end(); ++sdi) + { + cmLocalUnixMakefileGenerator3* slg = + static_cast<cmLocalUnixMakefileGenerator3*>(*sdi); + lg3Stack.push_back(slg); + } + } + } + return result; +} + //---------------------------------------------------------------------------- std::vector<cmTarget *>& cmGlobalUnixMakefileGenerator3 diff --git a/Source/cmGlobalUnixMakefileGenerator3.h b/Source/cmGlobalUnixMakefileGenerator3.h index 47557b96bf..a006808960 100644 --- a/Source/cmGlobalUnixMakefileGenerator3.h +++ b/Source/cmGlobalUnixMakefileGenerator3.h @@ -123,11 +123,10 @@ public: const char *targetName, const char* config, bool ignoreErrors, bool fast); - // returns true if a progress rule should be added - int ShouldAddProgressRule(); - int GetNumberOfCompilableSourceFilesForTarget(cmTarget &tgt); - int GetTargetTotalNumberOfProgressFiles(cmTarget& target); - int GetNumberOfSourceFiles() { return this->NumberOfSourceFiles; }; + // returns some progress informaiton + int GetTargetTotalNumberOfActions(cmTarget& target); + unsigned long GetNumberOfProgressActionsInAll + (cmLocalUnixMakefileGenerator3 *lg); // what targets does the specified target depend on std::vector<cmTarget *>& GetTargetDepends(cmTarget& target); @@ -183,9 +182,6 @@ protected: typedef std::map<cmStdString, cmStdString> MultipleOutputPairsType; MultipleOutputPairsType MultipleOutputPairs; - int NumberOfSourceFiles; - int NumberOfSourceFilesWritten; - std::map<cmStdString, std::vector<cmTarget *> > TargetDependencies; std::map<cmStdString, int > TargetSourceFileCount; }; diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index b9675f927a..0d687dee44 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -2081,3 +2081,120 @@ cmLocalGenerator } } } + +//---------------------------------------------------------------------------- +std::string& cmLocalGenerator::CreateSafeUniqueObjectFileName(const char* sin) +{ + // Look for an existing mapped name for this object file. + std::map<cmStdString,cmStdString>::iterator it = + this->UniqueObjectNamesMap.find(sin); + + // If no entry exists create one. + if(it == this->UniqueObjectNamesMap.end()) + { + // Start with the original name. + std::string ssin = sin; + + // Avoid full paths by removing leading slashes. + std::string::size_type pos = 0; + for(;pos < ssin.size() && ssin[pos] == '/'; ++pos); + ssin = ssin.substr(pos); + + // Avoid full paths by removing colons. + cmSystemTools::ReplaceString(ssin, ":", "_"); + + // Avoid relative paths that go up the tree. + cmSystemTools::ReplaceString(ssin, "../", "__/"); + + // Avoid spaces. + cmSystemTools::ReplaceString(ssin, " ", "_"); + + // Mangle the name if necessary. + if(this->Makefile->IsOn("CMAKE_MANGLE_OBJECT_FILE_NAMES")) + { + bool done; + int cc = 0; + char rpstr[100]; + sprintf(rpstr, "_p_"); + cmSystemTools::ReplaceString(ssin, "+", rpstr); + std::string sssin = sin; + do + { + done = true; + for ( it = this->UniqueObjectNamesMap.begin(); + it != this->UniqueObjectNamesMap.end(); + ++ it ) + { + if ( it->second == ssin ) + { + done = false; + } + } + if ( done ) + { + break; + } + sssin = ssin; + cmSystemTools::ReplaceString(ssin, "_p_", rpstr); + sprintf(rpstr, "_p%d_", cc++); + } + while ( !done ); + } + + // Insert the newly mapped object file name. + std::map<cmStdString, cmStdString>::value_type e(sin, ssin); + it = this->UniqueObjectNamesMap.insert(e).first; + } + + // Return the map entry. + return it->second; +} + +//---------------------------------------------------------------------------- +std::string +cmLocalGenerator::GetObjectFileNameWithoutTarget(const cmSourceFile& source) +{ + // If the source file is located below the current binary directory + // then use that relative path for the object file name. + std::string objectName = this->Convert(source.GetFullPath().c_str(), + START_OUTPUT); + if(cmSystemTools::FileIsFullPath(objectName.c_str()) || + objectName.empty() || objectName[0] == '.') + { + // If the source file is located below the current source + // directory then use that relative path for the object file name. + // Otherwise just use the relative path from the current binary + // directory. + std::string relFromSource = this->Convert(source.GetFullPath().c_str(), + START); + if(!cmSystemTools::FileIsFullPath(relFromSource.c_str()) && + !relFromSource.empty() && relFromSource[0] != '.') + { + objectName = relFromSource; + } + } + + // Replace the original source file extension with the object file + // extension. + std::string::size_type dot_pos = objectName.rfind("."); + if(dot_pos != std::string::npos) + { + objectName = objectName.substr(0, dot_pos); + } + if ( source.GetPropertyAsBool("KEEP_EXTENSION") ) + { + if ( !source.GetSourceExtension().empty() ) + { + objectName += "." + source.GetSourceExtension(); + } + } + else + { + objectName += + this->GlobalGenerator->GetLanguageOutputExtensionFromExtension( + source.GetSourceExtension().c_str()); + } + + // Convert to a safe name. + return this->CreateSafeUniqueObjectFileName(objectName.c_str()); +} diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index 6e4c60eab9..49bae5b7b0 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h @@ -254,6 +254,10 @@ protected: std::ostream& os, const char* config, std::vector<std::string> const& configurationTypes); + // Compute object file names. + std::string GetObjectFileNameWithoutTarget(const cmSourceFile& source); + std::string& CreateSafeUniqueObjectFileName(const char* sin); + cmMakefile *Makefile; cmGlobalGenerator *GlobalGenerator; // members used for relative path function ConvertToMakefilePath @@ -267,6 +271,7 @@ protected: cmLocalGenerator* Parent; std::vector<cmLocalGenerator*> Children; std::map<cmStdString, cmStdString> LanguageToIncludeFlags; + std::map<cmStdString, cmStdString> UniqueObjectNamesMap; bool WindowsShell; bool ForceUnixPath; bool UseRelativePaths; diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx index 8f7256729a..edfa61803a 100644 --- a/Source/cmLocalUnixMakefileGenerator3.cxx +++ b/Source/cmLocalUnixMakefileGenerator3.cxx @@ -100,17 +100,75 @@ void cmLocalUnixMakefileGenerator3::Generate() // Write the cmake file with information for this directory. this->WriteDirectoryInformationFile(); +} + +//---------------------------------------------------------------------------- +// return info about progress actions +unsigned long cmLocalUnixMakefileGenerator3::GetNumberOfProgressActions() +{ + unsigned long result = 0; + + for (std::vector<cmMakefileTargetGenerator *>::iterator mtgIter = + this->TargetGenerators.begin(); + mtgIter != this->TargetGenerators.end(); ++mtgIter) + { + result += (*mtgIter)->GetNumberOfProgressActions(); + } + return result; +} + +//---------------------------------------------------------------------------- +// return info about progress actions +unsigned long cmLocalUnixMakefileGenerator3 +::GetNumberOfProgressActionsForTarget(const char *name) +{ + for (std::vector<cmMakefileTargetGenerator *>::iterator mtgIter = + this->TargetGenerators.begin(); + mtgIter != this->TargetGenerators.end(); ++mtgIter) + { + if (!strcmp(name,(*mtgIter)->GetTargetName())) + { + return (*mtgIter)->GetNumberOfProgressActions(); + } + } + return 0; +} + +//---------------------------------------------------------------------------- +// writes the progreess variables and also closes out the targets +void cmLocalUnixMakefileGenerator3 +::WriteProgressVariables(unsigned long total, + unsigned long ¤t) +{ // delete the makefile target generator objects for (std::vector<cmMakefileTargetGenerator *>::iterator mtgIter = this->TargetGenerators.begin(); mtgIter != this->TargetGenerators.end(); ++mtgIter) { + (*mtgIter)->WriteProgressVariables(total,current); delete *mtgIter; } this->TargetGenerators.clear(); } +void cmLocalUnixMakefileGenerator3::WriteAllProgressVariable() +{ + // write the top level progress for the all target + std::string progressFileNameFull = + this->ConvertToFullPath("progress.make"); + cmGeneratedFileStream ruleFileStream(progressFileNameFull.c_str()); + if(!ruleFileStream) + { + return; + } + + cmGlobalUnixMakefileGenerator3 *gg = + static_cast<cmGlobalUnixMakefileGenerator3*>(this->GlobalGenerator); + + ruleFileStream << "CMAKE_ALL_PROGRESS = " + << gg->GetNumberOfProgressActionsInAll(this); +} //---------------------------------------------------------------------------- void cmLocalUnixMakefileGenerator3::ConfigureOutputPaths() @@ -192,6 +250,12 @@ void cmLocalUnixMakefileGenerator3::WriteLocalMakefile() ruleFileStream.SetCopyIfDifferent(true); } + // Include the progress variables for the target. + ruleFileStream + << "# Include the progress variables for this target.\n" + << this->IncludeDirective << " " + << "progress.make\n\n"; + // write the all rules this->WriteLocalAllRules(ruleFileStream); @@ -1001,75 +1065,6 @@ std::string cmLocalUnixMakefileGenerator3 } //---------------------------------------------------------------------------- -std::string& -cmLocalUnixMakefileGenerator3::CreateSafeUniqueObjectFileName(const char* sin) -{ - // Look for an existing mapped name for this object file. - std::map<cmStdString,cmStdString>::iterator it = - this->UniqueObjectNamesMap.find(sin); - - // If no entry exists create one. - if(it == this->UniqueObjectNamesMap.end()) - { - // Start with the original name. - std::string ssin = sin; - - // Avoid full paths by removing leading slashes. - std::string::size_type pos = 0; - for(;pos < ssin.size() && ssin[pos] == '/'; ++pos); - ssin = ssin.substr(pos); - - // Avoid full paths by removing colons. - cmSystemTools::ReplaceString(ssin, ":", "_"); - - // Avoid relative paths that go up the tree. - cmSystemTools::ReplaceString(ssin, "../", "__/"); - - // Avoid spaces. - cmSystemTools::ReplaceString(ssin, " ", "_"); - - // Mangle the name if necessary. - if(this->Makefile->IsOn("CMAKE_MANGLE_OBJECT_FILE_NAMES")) - { - bool done; - int cc = 0; - char rpstr[100]; - sprintf(rpstr, "_p_"); - cmSystemTools::ReplaceString(ssin, "+", rpstr); - std::string sssin = sin; - do - { - done = true; - for ( it = this->UniqueObjectNamesMap.begin(); - it != this->UniqueObjectNamesMap.end(); - ++ it ) - { - if ( it->second == ssin ) - { - done = false; - } - } - if ( done ) - { - break; - } - sssin = ssin; - cmSystemTools::ReplaceString(ssin, "_p_", rpstr); - sprintf(rpstr, "_p%d_", cc++); - } - while ( !done ); - } - - // Insert the newly mapped object file name. - std::map<cmStdString, cmStdString>::value_type e(sin, ssin); - it = this->UniqueObjectNamesMap.insert(e).first; - } - - // Return the map entry. - return it->second; -} - -//---------------------------------------------------------------------------- std::string cmLocalUnixMakefileGenerator3 ::CreateMakeVariable(const char* sin, const char* s2in) @@ -1450,22 +1445,12 @@ void cmLocalUnixMakefileGenerator3 progressDir += cmake::GetCMakeFilesDirectory(); { cmOStringStream progCmd; - progCmd << "$(CMAKE_COMMAND) -E cmake_progress_start "; // # src files + progCmd << + "$(CMAKE_COMMAND) -E cmake_progress_start "; progCmd << this->Convert(progressDir.c_str(), cmLocalGenerator::FULL, cmLocalGenerator::SHELL); - cmGlobalUnixMakefileGenerator3 *gg = - static_cast<cmGlobalUnixMakefileGenerator3*>(this->GlobalGenerator); - int n = gg->GetNumberOfSourceFiles(); - if(n > 100) - { - n = 100; - } - if (this->Parent) - { - n = 0; - } - progCmd << " " << n; + progCmd << " $(CMAKE_ALL_PROGRESS)"; commands.push_back(progCmd.str()); } std::string mf2Dir = cmake::GetCMakeFilesDirectoryPostSlash(); @@ -1475,7 +1460,6 @@ void cmLocalUnixMakefileGenerator3 this->CreateCDCommand(commands, this->Makefile->GetHomeOutputDirectory(), this->Makefile->GetStartOutputDirectory()); - if (!this->Parent) { cmOStringStream progCmd; progCmd << "$(CMAKE_COMMAND) -E cmake_progress_start "; // # 0 @@ -1656,56 +1640,20 @@ cmLocalUnixMakefileGenerator3 const cmSourceFile& source, std::string* nameWithoutTargetDir) { - // If the source file is located below the current binary directory - // then use that relative path for the object file name. - std::string objectName = this->Convert(source.GetFullPath().c_str(), - START_OUTPUT); - if(cmSystemTools::FileIsFullPath(objectName.c_str()) || - objectName.empty() || objectName[0] == '.') - { - // If the source file is located below the current source - // directory then use that relative path for the object file name. - // Otherwise just use the relative path from the current binary - // directory. - std::string relFromSource = this->Convert(source.GetFullPath().c_str(), - START); - if(!cmSystemTools::FileIsFullPath(relFromSource.c_str()) && - !relFromSource.empty() && relFromSource[0] != '.') - { - objectName = relFromSource; - } - } - - // Replace the original source file extension with the object file - // extension. - std::string::size_type dot_pos = objectName.rfind("."); - if(dot_pos != std::string::npos) - { - objectName = objectName.substr(0, dot_pos); - } - if ( source.GetPropertyAsBool("KEEP_EXTENSION") ) - { - if ( !source.GetSourceExtension().empty() ) - { - objectName += "." + source.GetSourceExtension(); - } - } - else + // Get the object file name independent of target. + std::string objectName = this->GetObjectFileNameWithoutTarget(source); + if(nameWithoutTargetDir) { - objectName += - this->GlobalGenerator->GetLanguageOutputExtensionFromExtension( - source.GetSourceExtension().c_str()); + *nameWithoutTargetDir = objectName; } - // Convert to a safe name. - objectName = this->CreateSafeUniqueObjectFileName(objectName.c_str()); - // Prepend the target directory. std::string obj; const char* fileTargetDirectory = source.GetProperty("MACOSX_PACKAGE_LOCATION"); if ( fileTargetDirectory ) { + objectName = cmSystemTools::GetFilenameName(objectName.c_str()); std::string targetName; std::string targetNameReal; target.GetExecutableNames(targetName, targetNameReal, @@ -1736,10 +1684,6 @@ cmLocalUnixMakefileGenerator3 } obj += "/"; obj += objectName; - if(nameWithoutTargetDir) - { - *nameWithoutTargetDir = objectName; - } return obj; } diff --git a/Source/cmLocalUnixMakefileGenerator3.h b/Source/cmLocalUnixMakefileGenerator3.h index bb72d13103..e7b60ba89a 100644 --- a/Source/cmLocalUnixMakefileGenerator3.h +++ b/Source/cmLocalUnixMakefileGenerator3.h @@ -78,6 +78,10 @@ public: // write the main variables used by the makefiles void WriteMakeVariables(std::ostream& makefileStream); + // write the progress variables used by the makefiles + void WriteProgressVariables(unsigned long total, unsigned long ¤t); + void WriteAllProgressVariable(); + /** * If true, then explicitly pass MAKEFLAGS on the make all target for makes * that do not use environment variables. @@ -165,7 +169,6 @@ public: static std::string ConvertToQuotedOutputPath(const char* p); - std::string& CreateSafeUniqueObjectFileName(const char* sin); std::string CreateMakeVariable(const char* sin, const char* s2in); // cleanup the name of a potential target @@ -208,6 +211,10 @@ public: std::map<cmStdString,std::vector<cmTarget *> > GetLocalObjectFiles() { return this->LocalObjectFiles;} + // return info about progress actions + unsigned long GetNumberOfProgressActions(); + unsigned long GetNumberOfProgressActionsForTarget(const char *); + protected: // these two methods just compute reasonable values for LibraryOutputPath // and ExecutableOutputPath @@ -319,7 +326,6 @@ private: std::vector<cmMakefileTargetGenerator *> TargetGenerators; std::map<cmStdString, cmStdString> MakeVariableMap; std::map<cmStdString, cmStdString> ShortMakeVariableMap; - std::map<cmStdString, cmStdString> UniqueObjectNamesMap; }; #endif diff --git a/Source/cmLocalVisualStudio6Generator.cxx b/Source/cmLocalVisualStudio6Generator.cxx index fc89ebd4f9..44246f3a4f 100644 --- a/Source/cmLocalVisualStudio6Generator.cxx +++ b/Source/cmLocalVisualStudio6Generator.cxx @@ -360,6 +360,9 @@ void cmLocalVisualStudio6Generator::WriteDSPFile(std::ostream& fout, } } + // Compute which sources need unique object computation. + this->ComputeObjectNameRequirements(sourceGroups); + // Write the DSP file's header. this->WriteDSPHeader(fout, libName, target, sourceGroups); @@ -404,6 +407,13 @@ void cmLocalVisualStudio6Generator (*sf)->GetCustomCommand(); std::string compileFlags; std::vector<std::string> depends; + std::string objectNameDir; + if(this->NeedObjectName.find(*sf) != this->NeedObjectName.end()) + { + objectNameDir = + cmSystemTools::GetFilenamePath( + this->GetObjectFileNameWithoutTarget(*(*sf))); + } // Add per-source file flags. if(const char* cflags = (*sf)->GetProperty("COMPILE_FLAGS")) @@ -464,7 +474,7 @@ void cmLocalVisualStudio6Generator comment.c_str(), command->GetDepends(), command->GetOutputs(), flags); } - else if(compileFlags.size()) + else if(!compileFlags.empty() || !objectNameDir.empty()) { for(std::vector<std::string>::iterator i = this->Configurations.begin(); @@ -478,8 +488,23 @@ void cmLocalVisualStudio6Generator { fout << "!ELSEIF \"$(CFG)\" == " << i->c_str() << std::endl; } + if(!compileFlags.empty()) + { fout << "\n# ADD CPP " << compileFlags << "\n\n"; } + if(!objectNameDir.empty()) + { + // Strip the subdirectory name out of the configuration name. + std::string config = *i; + std::string::size_type pos = config.find_last_of(" "); + config = config.substr(pos+1, std::string::npos); + config = config.substr(0, config.size()-1); + + // Setup an alternate object file directory. + fout << "\n# PROP Intermediate_Dir \"" + << config << "/" << objectNameDir << "\"\n\n"; + } + } fout << "!ENDIF\n\n"; } fout << "# End Source File\n"; diff --git a/Source/cmLocalVisualStudio6Generator.h b/Source/cmLocalVisualStudio6Generator.h index f2b4d13565..cdc246fbf6 100644 --- a/Source/cmLocalVisualStudio6Generator.h +++ b/Source/cmLocalVisualStudio6Generator.h @@ -17,7 +17,7 @@ #ifndef cmLocalVisualStudio6Generator_h #define cmLocalVisualStudio6Generator_h -#include "cmLocalGenerator.h" +#include "cmLocalVisualStudioGenerator.h" class cmMakeDepend; class cmTarget; @@ -31,7 +31,7 @@ class cmCustomCommand; * cmLocalVisualStudio6Generator produces a LocalUnix makefile from its * member this->Makefile. */ -class cmLocalVisualStudio6Generator : public cmLocalGenerator +class cmLocalVisualStudio6Generator : public cmLocalVisualStudioGenerator { public: ///! Set cache only and recurse to false by default. diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index a5eb3cd734..787cc9e81f 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -305,6 +305,7 @@ cmVS7FlagTable cmLocalVisualStudio7GeneratorFlagTable[] = {"EnableFunctionLevelLinking", "Gy", "EnableFunctionLevelLinking", "TRUE"}, {"EnableIntrinsicFunctions", "Oi", "EnableIntrinsicFunctions", "TRUE"}, {"ExceptionHandling", "EHsc", "enable c++ exceptions", "TRUE"}, + {"ExceptionHandling", "EHa", "enable c++ exceptions", "2"}, {"ExceptionHandling", "GX", "enable c++ exceptions", "TRUE"}, {"GlobalOptimizations", "Og", "Global Optimize", "TRUE"}, {"ImproveFloatingPointConsistency", "Op", @@ -1011,6 +1012,9 @@ void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout, sourceGroup.AssignSource(*i); } + // Compute which sources need unique object computation. + this->ComputeObjectNameRequirements(sourceGroups); + // open the project this->WriteProjectStart(fout, libName, target, sourceGroups); // write the configuration information @@ -1063,12 +1067,9 @@ void cmLocalVisualStudio7Generator const cmCustomCommand *command = (*sf)->GetCustomCommand(); std::string compileFlags; std::string additionalDeps; - objectName = (*sf)->GetSourceName(); - if(!(*sf)->GetPropertyAsBool("HEADER_FILE_ONLY" ) - && objectName.find("/") != objectName.npos) + if(this->NeedObjectName.find(*sf) != this->NeedObjectName.end()) { - cmSystemTools::ReplaceString(objectName, "/", "_"); - objectName += ".obj"; + objectName = this->GetObjectFileNameWithoutTarget(*(*sf)); } else { diff --git a/Source/cmLocalVisualStudio7Generator.h b/Source/cmLocalVisualStudio7Generator.h index 22d5d0b50c..ad81085e3b 100644 --- a/Source/cmLocalVisualStudio7Generator.h +++ b/Source/cmLocalVisualStudio7Generator.h @@ -17,7 +17,7 @@ #ifndef cmLocalVisualStudio7Generator_h #define cmLocalVisualStudio7Generator_h -#include "cmLocalGenerator.h" +#include "cmLocalVisualStudioGenerator.h" class cmMakeDepend; class cmTarget; @@ -27,12 +27,12 @@ class cmSourceGroup; struct cmVS7FlagTable; /** \class cmLocalVisualStudio7Generator - * \brief Write a LocalUnix makefiles. + * \brief Write Visual Studio .NET project files. * - * cmLocalVisualStudio7Generator produces a LocalUnix makefile from its - * member Makefile. + * cmLocalVisualStudio7Generator produces a Visual Studio .NET project + * file for each target in its directory. */ -class cmLocalVisualStudio7Generator : public cmLocalGenerator +class cmLocalVisualStudio7Generator : public cmLocalVisualStudioGenerator { public: ///! Set cache only and recurse to false by default. diff --git a/Source/cmLocalVisualStudioGenerator.cxx b/Source/cmLocalVisualStudioGenerator.cxx new file mode 100644 index 0000000000..b4ab9e240f --- /dev/null +++ b/Source/cmLocalVisualStudioGenerator.cxx @@ -0,0 +1,88 @@ +/*========================================================================= + + Program: CMake - Cross-Platform Makefile Generator + Module: $RCSfile$ + Language: C++ + Date: $Date$ + Version: $Revision$ + + Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved. + See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ +#include "cmLocalVisualStudioGenerator.h" + +#include "cmMakefile.h" +#include "cmSourceFile.h" +#include "cmSystemTools.h" + +//---------------------------------------------------------------------------- +cmLocalVisualStudioGenerator::cmLocalVisualStudioGenerator() +{ +} + +//---------------------------------------------------------------------------- +cmLocalVisualStudioGenerator::~cmLocalVisualStudioGenerator() +{ +} + +//---------------------------------------------------------------------------- +void cmLocalVisualStudioGenerator::ComputeObjectNameRequirements +(std::vector<cmSourceGroup> const& sourceGroups) +{ + // Clear the current set of requirements. + this->NeedObjectName.clear(); + + // Count the number of object files with each name. + std::map<cmStdString, int> objectNameCounts; + for(unsigned int i = 0; i < sourceGroups.size(); ++i) + { + cmSourceGroup sg = sourceGroups[i]; + std::vector<const cmSourceFile*> const& srcs = sg.GetSourceFiles(); + for(std::vector<const cmSourceFile*>::const_iterator s = srcs.begin(); + s != srcs.end(); ++s) + { + const cmSourceFile& sf = *(*s); + if(!sf.GetCustomCommand() && + !sf.GetPropertyAsBool("HEADER_FILE_ONLY") && + !sf.GetPropertyAsBool("EXTERNAL_OBJECT")) + { + std::string objectName = + cmSystemTools::GetFilenameWithoutLastExtension( + sf.GetFullPath().c_str()); + objectName += ".obj"; + objectNameCounts[objectName] += 1; + } + } + } + + // For all source files producing duplicate names we need unique + // object name computation. + for(unsigned int i = 0; i < sourceGroups.size(); ++i) + { + cmSourceGroup sg = sourceGroups[i]; + std::vector<const cmSourceFile*> const& srcs = sg.GetSourceFiles(); + for(std::vector<const cmSourceFile*>::const_iterator s = srcs.begin(); + s != srcs.end(); ++s) + { + const cmSourceFile* sf = *s; + if(!sf->GetCustomCommand() && + !sf->GetPropertyAsBool("HEADER_FILE_ONLY") && + !sf->GetPropertyAsBool("EXTERNAL_OBJECT")) + { + std::string objectName = + cmSystemTools::GetFilenameWithoutLastExtension( + sf->GetFullPath().c_str()); + objectName += ".obj"; + if(objectNameCounts[objectName] > 1) + { + this->NeedObjectName.insert(sf); + } + } + } + } +} diff --git a/Source/cmLocalVisualStudioGenerator.h b/Source/cmLocalVisualStudioGenerator.h new file mode 100644 index 0000000000..6fe0034b07 --- /dev/null +++ b/Source/cmLocalVisualStudioGenerator.h @@ -0,0 +1,43 @@ +/*========================================================================= + + Program: CMake - Cross-Platform Makefile Generator + Module: $RCSfile$ + Language: C++ + Date: $Date$ + Version: $Revision$ + + Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved. + See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ +#ifndef cmLocalVisualStudioGenerator_h +#define cmLocalVisualStudioGenerator_h + +#include "cmLocalGenerator.h" + +class cmSourceFile; +class cmSourceGroup; + +/** \class cmLocalVisualStudioGenerator + * \brief Base class for Visual Studio generators. + * + * cmLocalVisualStudioGenerator provides functionality common to all + * Visual Studio generators. + */ +class cmLocalVisualStudioGenerator : public cmLocalGenerator +{ +public: + cmLocalVisualStudioGenerator(); + virtual ~cmLocalVisualStudioGenerator(); + +protected: + // Safe object file name generation. + void ComputeObjectNameRequirements(std::vector<cmSourceGroup> const&); + std::set<const cmSourceFile*> NeedObjectName; +}; + +#endif diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index d4cc69da6c..5027021ed1 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -90,6 +90,47 @@ cmMakefile::cmMakefile() this->PreOrder = false; } +cmMakefile::cmMakefile(const cmMakefile& mf) +{ + this->Prefix = mf.Prefix; + this->AuxSourceDirectories = mf.AuxSourceDirectories; + this->cmStartDirectory = mf.cmStartDirectory; + this->StartOutputDirectory = mf.StartOutputDirectory; + this->cmHomeDirectory = mf.cmHomeDirectory; + this->HomeOutputDirectory = mf.HomeOutputDirectory; + this->cmCurrentListFile = mf.cmCurrentListFile; + this->ProjectName = mf.ProjectName; + this->Targets = mf.Targets; + this->SourceFiles = mf.SourceFiles; + this->Tests = mf.Tests; + this->IncludeDirectories = mf.IncludeDirectories; + this->LinkDirectories = mf.LinkDirectories; + this->ListFiles = mf.ListFiles; + this->OutputFiles = mf.OutputFiles; + this->LinkLibraries = mf.LinkLibraries; + this->InstallGenerators = mf.InstallGenerators; + this->IncludeFileRegularExpression = mf.IncludeFileRegularExpression; + this->ComplainFileRegularExpression = mf.ComplainFileRegularExpression; + this->SourceFileExtensions = mf.SourceFileExtensions; + this->HeaderFileExtensions = mf.HeaderFileExtensions; + this->DefineFlags = mf.DefineFlags; + +#if defined(CMAKE_BUILD_WITH_CMAKE) + this->SourceGroups = mf.SourceGroups; +#endif + + this->Definitions = mf.Definitions; + this->LocalGenerator = mf.LocalGenerator; + this->FunctionBlockers = mf.FunctionBlockers; + this->DataMap = mf.DataMap; + this->MacrosMap = mf.MacrosMap; + this->SubDirectoryOrder = mf.SubDirectoryOrder; + this->TemporaryDefinitionKey = mf.TemporaryDefinitionKey; + this->Properties = mf.Properties; + this->PreOrder = mf.PreOrder; + this->ListFileStack = mf.ListFileStack; +} + const char* cmMakefile::GetReleaseVersion() { #if CMake_VERSION_MINOR & 1 diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index 7751a03d72..632bf1f079 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -69,6 +69,7 @@ public: * Construct an empty makefile. */ cmMakefile(); + cmMakefile(const cmMakefile& mf); /** * Destructor. diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx index 03b0cd23ab..2f9c0663b6 100644 --- a/Source/cmMakefileExecutableTargetGenerator.cxx +++ b/Source/cmMakefileExecutableTargetGenerator.cxx @@ -76,6 +76,11 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) obj != this->Objects.end(); ++obj) { objTarget = relPath; + // Handle extra content on Mac bundles + if ( this->ExtraContent.find(*obj) != this->ExtraContent.end() ) + { + objTarget = ""; + } objTarget += *obj; depends.push_back(objTarget); } diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index a4f03c8c9e..35e57cf222 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -85,6 +85,15 @@ void cmMakefileTargetGenerator::CreateRuleFile() this->BuildFileNameFull = this->TargetBuildDirectoryFull; this->BuildFileNameFull += "/build.make"; + // Construct the rule file name. + this->ProgressFileName = this->TargetBuildDirectory; + this->ProgressFileName += "/progress.make"; + this->ProgressFileNameFull = this->TargetBuildDirectoryFull; + this->ProgressFileNameFull += "/progress.make"; + + // reset the progress count + this->NumberOfProgressActions = 0; + // Open the rule file. This should be copy-if-different because the // rules may depend on this file itself. this->BuildFileStream = @@ -178,6 +187,15 @@ void cmMakefileTargetGenerator::WriteCommonCodeRules() cmLocalGenerator::MAKEFILE) << "\n\n"; + // Include the progress variables for the target. + *this->BuildFileStream + << "# Include the progress variables for this target.\n" + << this->LocalGenerator->IncludeDirective << " " + << this->Convert(this->ProgressFileNameFull.c_str(), + cmLocalGenerator::HOME_OUTPUT, + cmLocalGenerator::MAKEFILE) + << "\n\n"; + // make sure the depend file exists if (!cmSystemTools::FileExists(dependFileNameFull.c_str())) { @@ -309,8 +327,12 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(cmSourceFile& source) this->ExtraContent.insert(obj); } this->Objects.push_back(obj); - std::string relativeObj = this->LocalGenerator->GetHomeRelativeOutputPath(); - relativeObj += obj; + + // TODO: Remove + //std::string relativeObj + //= this->LocalGenerator->GetHomeRelativeOutputPath(); + //relativeObj += obj; + // we compute some depends when writing the depend.make that we will also // use in the build.make, same with depMakeFile std::vector<std::string> depends; @@ -346,6 +368,10 @@ cmMakefileTargetGenerator this->WriteObjectDependRules(source, depends); std::string relativeObj = this->LocalGenerator->GetHomeRelativeOutputPath(); + if ( source.GetPropertyAsBool("MACOSX_CONTENT") ) + { + relativeObj = ""; + } relativeObj += obj; if(this->Makefile->GetDefinition("CMAKE_WINDOWS_OBJECT_PATH")) { @@ -400,10 +426,6 @@ cmMakefileTargetGenerator std::vector<std::string> commands; // add in a progress call if needed - cmGlobalUnixMakefileGenerator3* gg = - static_cast<cmGlobalUnixMakefileGenerator3*>(this->GlobalGenerator); - int prog = gg->ShouldAddProgressRule(); - std::string progressDir = this->Makefile->GetHomeOutputDirectory(); progressDir += cmake::GetCMakeFilesDirectory(); cmOStringStream progCmd; @@ -411,12 +433,10 @@ cmMakefileTargetGenerator progCmd << this->LocalGenerator->Convert(progressDir.c_str(), cmLocalGenerator::FULL, cmLocalGenerator::SHELL); - if (prog) - { - progCmd << " " << prog; - this->LocalGenerator->ProgressFiles[this->Target->GetName()]. - push_back(prog); - } + this->NumberOfProgressActions++; + progCmd << " $(CMAKE_PROGRESS_" + << this->NumberOfProgressActions + << ")"; commands.push_back(progCmd.str()); std::string buildEcho = "Building "; @@ -688,6 +708,19 @@ void cmMakefileTargetGenerator std::string comment = this->LocalGenerator->ConstructComment(cc); if(!comment.empty()) { + // add in a progress call if needed + std::string progressDir = this->Makefile->GetHomeOutputDirectory(); + progressDir += cmake::GetCMakeFilesDirectory(); + cmOStringStream progCmd; + progCmd << "$(CMAKE_COMMAND) -E cmake_progress_report "; + progCmd << this->LocalGenerator->Convert(progressDir.c_str(), + cmLocalGenerator::FULL, + cmLocalGenerator::SHELL); + this->NumberOfProgressActions++; + progCmd << " $(CMAKE_PROGRESS_" + << this->NumberOfProgressActions + << ")"; + commands.push_back(progCmd.str()); this->LocalGenerator ->AppendEcho(commands, comment.c_str(), cmLocalUnixMakefileGenerator3::EchoGenerate); @@ -1023,3 +1056,40 @@ void cmMakefileTargetGenerator::RemoveForbiddenFlags(const char* flagVar, cmSystemTools::ReplaceString(linkFlags, i->c_str(), ""); } } + +void cmMakefileTargetGenerator::WriteProgressVariables(unsigned long total, + unsigned long ¤t) +{ + cmGeneratedFileStream *progressFileStream = + new cmGeneratedFileStream(this->ProgressFileNameFull.c_str()); + if(!progressFileStream) + { + return; + } + + unsigned long num; + unsigned long i; + for (i = 1; i <= this->NumberOfProgressActions; ++i) + { + *progressFileStream + << "CMAKE_PROGRESS_" << i << " = "; + if (total <= 100) + { + num = i + current; + *progressFileStream << num; + this->LocalGenerator->ProgressFiles[this->Target->GetName()] + .push_back(num); + } + else if (((i+current)*100)/total > ((i-1+current)*100)/total) + { + num = ((i+current)*100)/total; + *progressFileStream << num; + this->LocalGenerator->ProgressFiles[this->Target->GetName()] + .push_back(num); + } + *progressFileStream << "\n"; + } + current += this->NumberOfProgressActions; + delete progressFileStream; +} + diff --git a/Source/cmMakefileTargetGenerator.h b/Source/cmMakefileTargetGenerator.h index a62430592b..02223e6ded 100644 --- a/Source/cmMakefileTargetGenerator.h +++ b/Source/cmMakefileTargetGenerator.h @@ -50,6 +50,17 @@ public: with this target */ virtual void WriteRuleFiles() = 0; + /* the main entry point for this class. Writes the Makefiles associated + with this target */ + virtual void WriteProgressVariables(unsigned long total, + unsigned long ¤t); + + /* return the number of actions that have progress reporting on them */ + virtual unsigned long GetNumberOfProgressActions() { + return this->NumberOfProgressActions;} + + const char *GetTargetName() { return this->TargetName.c_str(); } + protected: // create the file and directory etc @@ -115,6 +126,11 @@ protected: std::string BuildFileName; std::string BuildFileNameFull; + // the full path to the progress file + std::string ProgressFileName; + std::string ProgressFileNameFull; + unsigned long NumberOfProgressActions; + // the path to the directory the build file is in std::string TargetBuildDirectory; std::string TargetBuildDirectoryFull; diff --git a/Source/cmSetSourceFilesPropertiesCommand.cxx b/Source/cmSetSourceFilesPropertiesCommand.cxx index 1884328ae5..8c085ffb62 100644 --- a/Source/cmSetSourceFilesPropertiesCommand.cxx +++ b/Source/cmSetSourceFilesPropertiesCommand.cxx @@ -110,6 +110,8 @@ bool cmSetSourceFilesPropertiesCommand::InitialPass( propertyPairs.push_back(*j); propertyPairs.push_back("EXTRA_CONTENT"); propertyPairs.push_back("1"); + propertyPairs.push_back("MACOSX_CONTENT"); + propertyPairs.push_back("1"); propertyPairs.push_back("KEEP_EXTENSION"); propertyPairs.push_back("1"); propertyPairs.push_back("LANGUAGE"); diff --git a/Source/cmStandardIncludes.h b/Source/cmStandardIncludes.h index f40945c6f3..39a605929b 100644 --- a/Source/cmStandardIncludes.h +++ b/Source/cmStandardIncludes.h @@ -341,7 +341,7 @@ static thisClass* SafeDownCast(cmObject *c) \ { \ if ( c && c->IsA(#thisClass) ) \ { \ - return (thisClass *)c; \ + return static_cast<thisClass *>(c); \ } \ return 0;\ } diff --git a/Source/cmake.cxx b/Source/cmake.cxx index 2c64d2e7fd..275c32dc1f 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -942,11 +942,11 @@ int cmake::ExecuteCMakeCommand(std::vector<std::string>& args) clock_finish = clock(); time(&time_finish); - double clocks_per_sec = (double)CLOCKS_PER_SEC; + double clocks_per_sec = static_cast<double>(CLOCKS_PER_SEC); std::cout << "Elapsed time: " - << (long)(time_finish - time_start) << " s. (time)" + << static_cast<long>(time_finish - time_start) << " s. (time)" << ", " - << (double)(clock_finish - clock_start) / clocks_per_sec + << static_cast<double>(clock_finish - clock_start) / clocks_per_sec << " s. (clock)" << "\n"; return 0; @@ -2368,7 +2368,6 @@ void cmake::GenerateGraphViz(const char* fileName) std::map<cmStdString, int> targetDeps; std::map<cmStdString, cmTarget*> targetPtrs; std::map<cmStdString, cmStdString> targetNamesNodes; - char tgtName[2048]; int cnt = 0; // First pass get the list of all cmake targets for ( lit = localGenerators.begin(); lit != localGenerators.end(); ++ lit ) @@ -2384,8 +2383,9 @@ void cmake::GenerateGraphViz(const char* fileName) continue; } //std::cout << "Found target: " << tit->first.c_str() << std::endl; - sprintf(tgtName, "%s%d", graphNodePrefix, cnt++); - targetNamesNodes[realTargetName] = tgtName; + cmOStringStream ostr; + ostr << graphNodePrefix << cnt++; + targetNamesNodes[realTargetName] = ostr.str(); targetPtrs[realTargetName] = &tit->second; } } @@ -2421,10 +2421,11 @@ void cmake::GenerateGraphViz(const char* fileName) } if ( tarIt == targetNamesNodes.end() ) { - sprintf(tgtName, "%s%d", graphNodePrefix, cnt++); + cmOStringStream ostr; + ostr << graphNodePrefix << cnt++; targetDeps[libName] = 2; - targetNamesNodes[libName] = tgtName; - //str << " \"" << tgtName << "\" [ label=\"" << libName + targetNamesNodes[libName] = ostr.str(); + //str << " \"" << ostr.c_str() << "\" [ label=\"" << libName //<< "\" shape=\"ellipse\"];" << std::endl; } else @@ -2553,7 +2554,8 @@ int cmake::ExecuteEchoColor(std::vector<std::string>& args) // likely no. int assumeTTY = cmsysTerminal_Color_AssumeTTY; if(cmSystemTools::GetEnv("DART_TEST_FROM_DART") || - cmSystemTools::GetEnv("DASHBOARD_TEST_FROM_CTEST")) + cmSystemTools::GetEnv("DASHBOARD_TEST_FROM_CTEST") || + cmSystemTools::GetEnv("CTEST_INTERACTIVE_DEBUG_MODE")) { // Avoid printing color escapes during dashboard builds. assumeTTY = 0; diff --git a/Source/kwsys/CMakeLists.txt b/Source/kwsys/CMakeLists.txt index 2269db020d..2145b7d482 100644 --- a/Source/kwsys/CMakeLists.txt +++ b/Source/kwsys/CMakeLists.txt @@ -37,6 +37,41 @@ # SET(KWSYS_HEADER_ROOT ${PROJECT_BINARY_DIR}) # INCLUDE_DIRECTORIES(${PROJECT_BINARY_DIR}) # +# KWSYS_IOS_FORCE_OLD = Force use of old non-ANSI C++ streams even if +# new streams are available. This may be used +# by projects that cannot configure their +# streams library. +# Example: +# +# SET(KWSYS_IOS_FORCE_OLD 1) +# +# +# Optional settings to setup install rules work in one of two ways. +# The modern way utilizes the CMake 2.4 INSTALL command. Settings +# for this mode are as follows: +# +# KWSYS_INSTALL_BIN_DIR = The installation target directories into +# KWSYS_INSTALL_LIB_DIR which the libraries and headers from +# KWSYS_INSTALL_INCLUDE_DIR kwsys should be installed by a "make install". +# The values should be specified relative to +# the installation prefix and NOT start with '/'. +# +# KWSYS_INSTALL_COMPONENT_NAME_RUNTIME = Name of runtime and development +# KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT installation components. +# If not given the install rules +# will not be in any component. +# +# Example: +# +# SET(KWSYS_INSTALL_BIN_DIR bin) +# SET(KWSYS_INSTALL_LIB_DIR lib) +# SET(KWSYS_INSTALL_INCLUDE_DIR include) +# SET(KWSYS_INSTALL_COMPONENT_NAME_RUNTIME Runtime) +# SET(KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT Development) +# +# The old way uses the original CMake INSTALL_* commands. Settings +# for this mode are as follows: +# # KWSYS_LIBRARY_INSTALL_DIR = The installation target directories into # KWSYS_HEADER_INSTALL_DIR which the libraries and headers from # kwsys should be installed by a "make install". @@ -47,14 +82,11 @@ # SET(KWSYS_LIBRARY_INSTALL_DIR /lib) # SET(KWSYS_HEADER_INSTALL_DIR /include) # -# KWSYS_IOS_FORCE_OLD = Force use of old non-ANSI C++ streams even if -# new streams are available. This may be used -# by projects that cannot configure their -# streams library. -# Example: -# -# SET(KWSYS_IOS_FORCE_OLD 1) -# +# The modern way will be used whenever the INSTALL command is +# available. If the settings are not available the old names will be +# used to construct them. The old way will be used whenever the +# INSTALL command is not available. If the settings are not available +# the new names will be used to construct them. # Once configured, kwsys should be used as follows from C or C++ code: # @@ -113,6 +145,87 @@ ENDIF(KWSYS_STANDALONE) # Do full dependency headers. INCLUDE_REGULAR_EXPRESSION("^.*$") +# Choose which kind of install commands to use. +IF(COMMAND INSTALL) + # Use new KWSYS_INSTALL_*_DIR variable names to control installation. + # Take defaults from the old names. Note that there was no old name + # for the bin dir, so we take the old lib dir name so DLLs will be + # installed in a compatible way for old code. + IF(NOT KWSYS_INSTALL_INCLUDE_DIR) + STRING(REGEX REPLACE "^/" "" KWSYS_INSTALL_INCLUDE_DIR + "${KWSYS_HEADER_INSTALL_DIR}") + ENDIF(NOT KWSYS_INSTALL_INCLUDE_DIR) + IF(NOT KWSYS_INSTALL_LIB_DIR) + STRING(REGEX REPLACE "^/" "" KWSYS_INSTALL_LIB_DIR + "${KWSYS_LIBRARY_INSTALL_DIR}") + ENDIF(NOT KWSYS_INSTALL_LIB_DIR) + IF(NOT KWSYS_INSTALL_BIN_DIR) + STRING(REGEX REPLACE "^/" "" KWSYS_INSTALL_BIN_DIR + "${KWSYS_LIBRARY_INSTALL_DIR}") + ENDIF(NOT KWSYS_INSTALL_BIN_DIR) + + # Setup library install rules. + SET(KWSYS_INSTALL_LIBRARY_RULE) + IF(KWSYS_INSTALL_LIB_DIR) + # Install the shared library to the lib directory. + SET(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE} + LIBRARY DESTINATION ${KWSYS_INSTALL_LIB_DIR} + ) + # Assign the shared library to the runtime component. + IF(KWSYS_INSTALL_COMPONENT_NAME_RUNTIME) + SET(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE} + COMPONENT ${KWSYS_INSTALL_COMPONENT_NAME_RUNTIME} + ) + ENDIF(KWSYS_INSTALL_COMPONENT_NAME_RUNTIME) + + # Install the archive to the lib directory. + SET(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE} + ARCHIVE DESTINATION ${KWSYS_INSTALL_LIB_DIR} + ) + # Assign the archive to the development component. + IF(KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT) + SET(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE} + COMPONENT ${KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT} + ) + ENDIF(KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT) + ENDIF(KWSYS_INSTALL_LIB_DIR) + IF(KWSYS_INSTALL_BIN_DIR) + # Install the runtime library to the bin directory. + SET(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE} + RUNTIME DESTINATION ${KWSYS_INSTALL_BIN_DIR} + ) + # Assign the runtime library to the runtime component. + IF(KWSYS_INSTALL_COMPONENT_NAME_RUNTIME) + SET(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE} + COMPONENT ${KWSYS_INSTALL_COMPONENT_NAME_RUNTIME} + ) + ENDIF(KWSYS_INSTALL_COMPONENT_NAME_RUNTIME) + ENDIF(KWSYS_INSTALL_BIN_DIR) + + # Do not support old KWSYS_*_INSTALL_DIR variable names. + SET(KWSYS_HEADER_INSTALL_DIR) + SET(KWSYS_LIBRARY_INSTALL_DIR) + +ELSE(COMMAND INSTALL) + # Use old KWSYS_*_INSTALL_DIR variable names. + # Take defaults from the new names. + IF(KWSYS_INSTALL_LIB_DIR) + IF(NOT KWSYS_LIBRARY_INSTALL_DIR) + SET(KWSYS_LIBRARY_INSTALL_DIR "/${KWSYS_INSTALL_LIB_DIR}") + ENDIF(NOT KWSYS_LIBRARY_INSTALL_DIR) + ENDIF(KWSYS_INSTALL_LIB_DIR) + IF(KWSYS_INSTALL_INCLUDE_DIR) + IF(NOT KWSYS_HEADER_INSTALL_DIR) + SET(KWSYS_HEADER_INSTALL_DIR "/${KWSYS_INSTALL_INCLUDE_DIR}") + ENDIF(NOT KWSYS_HEADER_INSTALL_DIR) + ENDIF(KWSYS_INSTALL_INCLUDE_DIR) + + # Do not support new KWSYS_INSTALL_*_DIR variable names. + SET(KWSYS_INSTALL_BIN_DIR) + SET(KWSYS_INSTALL_INCLUDE_DIR) + SET(KWSYS_INSTALL_LIB_DIR) +ENDIF(COMMAND INSTALL) + # Work-around for CMake 1.6.7 bug in custom command dependencies when # there is no executable output path. IF(NOT EXECUTABLE_OUTPUT_PATH) @@ -369,6 +482,10 @@ FOREACH(header algorithm deque iterator list map numeric queue set stack string CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/kwsys_stl_${header}.hxx.in ${KWSYS_HEADER_DIR}/stl/${header}.hxx @ONLY IMMEDIATE) + IF(KWSYS_INSTALL_INCLUDE_DIR) + INSTALL(FILES ${KWSYS_HEADER_DIR}/stl/${header}.hxx + DESTINATION ${KWSYS_INSTALL_INCLUDE_DIR}/${KWSYS_NAMESPACE}/stl) + ENDIF(KWSYS_INSTALL_INCLUDE_DIR) IF(KWSYS_HEADER_INSTALL_DIR) INSTALL_FILES(${KWSYS_HEADER_INSTALL_DIR}/${KWSYS_NAMESPACE}/stl FILES ${KWSYS_HEADER_DIR}/stl/${header}.hxx) @@ -381,6 +498,10 @@ FOREACH(header algorithm deque iterator list map numeric queue set stack string @ONLY IMMEDIATE) # Create an install target for the header wrapper. + IF(KWSYS_INSTALL_INCLUDE_DIR) + INSTALL(FILES ${KWSYS_HEADER_DIR}/stl/${header} + DESTINATION ${KWSYS_INSTALL_INCLUDE_DIR}/${KWSYS_NAMESPACE}/stl) + ENDIF(KWSYS_INSTALL_INCLUDE_DIR) IF(KWSYS_HEADER_INSTALL_DIR) INSTALL_FILES(${KWSYS_HEADER_INSTALL_DIR}/${KWSYS_NAMESPACE}/stl FILES ${KWSYS_HEADER_DIR}/stl/${header}) @@ -402,6 +523,10 @@ FOREACH(header iostream fstream sstream iosfwd) @ONLY IMMEDIATE) # Create an install target for the header wrapper. + IF(KWSYS_INSTALL_INCLUDE_DIR) + INSTALL(FILES ${KWSYS_HEADER_DIR}/ios/${header} + DESTINATION ${KWSYS_INSTALL_INCLUDE_DIR}/${KWSYS_NAMESPACE}/ios) + ENDIF(KWSYS_INSTALL_INCLUDE_DIR) IF(KWSYS_HEADER_INSTALL_DIR) INSTALL_FILES(${KWSYS_HEADER_INSTALL_DIR}/${KWSYS_NAMESPACE}/ios FILES ${KWSYS_HEADER_DIR}/ios/${header}) @@ -481,6 +606,10 @@ FOREACH(c ${KWSYS_CLASSES}) @ONLY IMMEDIATE) # Create an install target for the header. + IF(KWSYS_INSTALL_INCLUDE_DIR) + INSTALL(FILES ${KWSYS_HEADER_DIR}/${c}.hxx + DESTINATION ${KWSYS_INSTALL_INCLUDE_DIR}/${KWSYS_NAMESPACE}) + ENDIF(KWSYS_INSTALL_INCLUDE_DIR) IF(KWSYS_HEADER_INSTALL_DIR) INSTALL_FILES(${KWSYS_HEADER_INSTALL_DIR}/${KWSYS_NAMESPACE} FILES ${KWSYS_HEADER_DIR}/${c}.hxx) @@ -494,6 +623,10 @@ FOREACH(h ${KWSYS_H_FILES}) @ONLY IMMEDIATE) # Create an install target for the header. + IF(KWSYS_INSTALL_INCLUDE_DIR) + INSTALL(FILES ${KWSYS_HEADER_DIR}/${h}.h + DESTINATION ${KWSYS_INSTALL_INCLUDE_DIR}/${KWSYS_NAMESPACE}) + ENDIF(KWSYS_INSTALL_INCLUDE_DIR) IF(KWSYS_HEADER_INSTALL_DIR) INSTALL_FILES(${KWSYS_HEADER_INSTALL_DIR}/${KWSYS_NAMESPACE} FILES ${KWSYS_HEADER_DIR}/${h}.h) @@ -507,6 +640,10 @@ FOREACH(h ${KWSYS_HXX_FILES}) @ONLY IMMEDIATE) # Create an install target for the header. + IF(KWSYS_INSTALL_INCLUDE_DIR) + INSTALL(FILES ${KWSYS_HEADER_DIR}/${h}.hxx + DESTINATION ${KWSYS_INSTALL_INCLUDE_DIR}/${KWSYS_NAMESPACE}) + ENDIF(KWSYS_INSTALL_INCLUDE_DIR) IF(KWSYS_HEADER_INSTALL_DIR) INSTALL_FILES(${KWSYS_HEADER_INSTALL_DIR}/${KWSYS_NAMESPACE} FILES ${KWSYS_HEADER_DIR}/${h}.hxx) @@ -532,6 +669,9 @@ IF(KWSYS_C_SRCS OR KWSYS_CXX_SRCS) ENDIF(KWSYS_PROPERTIES_CXX) # Create an install target for the library. + IF(KWSYS_INSTALL_LIBRARY_RULE) + INSTALL(TARGETS ${KWSYS_NAMESPACE} ${KWSYS_INSTALL_LIBRARY_RULE}) + ENDIF(KWSYS_INSTALL_LIBRARY_RULE) IF(KWSYS_LIBRARY_INSTALL_DIR) INSTALL_TARGETS(${KWSYS_LIBRARY_INSTALL_DIR} ${KWSYS_NAMESPACE}) ENDIF(KWSYS_LIBRARY_INSTALL_DIR) @@ -549,6 +689,9 @@ IF(KWSYS_ENABLE_C AND KWSYS_C_SRCS) ENDIF(KWSYS_PROPERTIES_C) # Create an install target for the library. + IF(KWSYS_INSTALL_LIBRARY_RULE) + INSTALL(TARGETS ${KWSYS_NAMESPACE}_c ${KWSYS_INSTALL_LIBRARY_RULE}) + ENDIF(KWSYS_INSTALL_LIBRARY_RULE) IF(KWSYS_LIBRARY_INSTALL_DIR) INSTALL_TARGETS(${KWSYS_LIBRARY_INSTALL_DIR} ${KWSYS_NAMESPACE}_c) ENDIF(KWSYS_LIBRARY_INSTALL_DIR) @@ -625,6 +768,7 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR) testIOS testHashSTL testCommandLineArguments + testCommandLineArguments1 testRegistry ${EXTRA_TESTS} ) @@ -676,6 +820,32 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR) ENDIF(NOT CYGWIN) ADD_TEST(kwsys.testHashSTL ${EXEC_DIR}/testHashSTL) ADD_TEST(kwsys.testRegistry ${EXEC_DIR}/testRegistry) + ADD_TEST(kwsys.testCommandLineArguments ${EXEC_DIR}/testCommandLineArguments + --another-bool-variable + --long3=opt + --set-bool-arg1 + -SSS ken brad bill andy + --some-bool-variable=true + --some-double-variable12.5 + --some-int-variable 14 + "--some-string-variable=test string with space" + --some-multi-argument 5 1 8 3 7 1 3 9 7 1 + -N 12.5 -SS=andy -N 1.31 -N 22 + -SS=bill -BBtrue -SS=brad + -BBtrue + -BBfalse + -SS=ken + -A + -C=test + --long2 hello) + ADD_TEST(kwsys.testCommandLineArguments1 ${EXEC_DIR}/testCommandLineArguments1 + --ignored + -n 24 + --second-ignored + "-m=test value" + third-ignored + -p + some junk at the end) IF(COMMAND SET_TESTS_PROPERTIES AND COMMAND GET_TEST_PROPERTY AND KWSYS_STANDALONE) ADD_TEST(kwsys.testFail ${EXEC_DIR}/testFail) # We expect test to fail diff --git a/Source/kwsys/CommandLineArguments.cxx b/Source/kwsys/CommandLineArguments.cxx index cdf254f7d9..586d6fd661 100644 --- a/Source/kwsys/CommandLineArguments.cxx +++ b/Source/kwsys/CommandLineArguments.cxx @@ -15,6 +15,7 @@ #include KWSYS_HEADER(CommandLineArguments.hxx) #include KWSYS_HEADER(Configure.hxx) +#include KWSYS_HEADER(String.hxx) #include KWSYS_HEADER(stl/vector) #include KWSYS_HEADER(stl/map) @@ -44,22 +45,18 @@ # pragma set woff 1375 /* base class destructor not virtual */ #endif +#if 0 +# define CommandLineArguments_DEBUG(x) \ + kwsys_ios::cout << __LINE__ << " CLA: " << x << kwsys_ios::endl +#else +# define CommandLineArguments_DEBUG(x) +#endif + namespace KWSYS_NAMESPACE { //---------------------------------------------------------------------------- //============================================================================ -class CommandLineArgumentsString : public kwsys_stl::string -{ -public: - typedef kwsys_stl::string StdString; - CommandLineArgumentsString(): StdString() {} - CommandLineArgumentsString(const value_type* s): StdString(s) {} - CommandLineArgumentsString(const value_type* s, size_type n): StdString(s, n) {} - CommandLineArgumentsString(const StdString& s, size_type pos=0, size_type n=npos): - StdString(s, pos, n) {} -}; - struct CommandLineArgumentsCallbackStructure { const char* Argument; @@ -72,11 +69,11 @@ struct CommandLineArgumentsCallbackStructure }; class CommandLineArgumentsVectorOfStrings : - public kwsys_stl::vector<CommandLineArgumentsString> {}; + public kwsys_stl::vector<kwsys::String> {}; class CommandLineArgumentsSetOfStrings : - public kwsys_stl::set<CommandLineArgumentsString> {}; + public kwsys_stl::set<kwsys::String> {}; class CommandLineArgumentsMapOfStrucs : - public kwsys_stl::map<CommandLineArgumentsString, + public kwsys_stl::map<kwsys::String, CommandLineArgumentsCallbackStructure> {}; class CommandLineArgumentsInternal @@ -91,7 +88,7 @@ public: typedef CommandLineArgumentsVectorOfStrings VectorOfStrings; typedef CommandLineArgumentsMapOfStrucs CallbacksMap; - typedef CommandLineArgumentsString String; + typedef kwsys::String String; typedef CommandLineArgumentsSetOfStrings SetOfStrings; VectorOfStrings Argv; @@ -102,6 +99,8 @@ public: void* ClientData; VectorOfStrings::size_type LastArgument; + + VectorOfStrings UnusedArguments; }; //============================================================================ //---------------------------------------------------------------------------- @@ -112,6 +111,7 @@ CommandLineArguments::CommandLineArguments() this->Internals = new CommandLineArguments::Internal; this->Help = ""; this->LineLength = 80; + this->StoreUnusedArgumentsFlag = false; } //---------------------------------------------------------------------------- @@ -153,15 +153,11 @@ void CommandLineArguments::ProcessArgument(const char* arg) } //---------------------------------------------------------------------------- -int CommandLineArguments::Parse() +bool CommandLineArguments::GetMatchedArguments( + kwsys_stl::vector<kwsys_stl::string>* matches, + const kwsys_stl::string& arg) { - CommandLineArguments::Internal::VectorOfStrings::size_type cc; - CommandLineArguments::Internal::VectorOfStrings matches; - for ( cc = 0; cc < this->Internals->Argv.size(); cc ++ ) - { - this->Internals->LastArgument = cc; - matches.clear(); - CommandLineArguments::Internal::String& arg = this->Internals->Argv[cc]; + matches->clear(); CommandLineArguments::Internal::CallbacksMap::iterator it; // Does the argument match to any we know about? @@ -176,15 +172,32 @@ int CommandLineArguments::Parse() { if ( arg == parg ) { - matches.push_back(parg); + matches->push_back(parg); } } else if ( arg.find( parg ) == 0 ) { - matches.push_back(parg); + matches->push_back(parg); } } - if ( matches.size() > 0 ) + return matches->size() > 0; +} + +//---------------------------------------------------------------------------- +int CommandLineArguments::Parse() +{ + kwsys_stl::vector<kwsys_stl::string>::size_type cc; + kwsys_stl::vector<kwsys_stl::string> matches; + if ( this->StoreUnusedArgumentsFlag ) + { + this->Internals->UnusedArguments.clear(); + } + for ( cc = 0; cc < this->Internals->Argv.size(); cc ++ ) + { + const kwsys_stl::string& arg = this->Internals->Argv[cc]; + CommandLineArguments_DEBUG("Process argument: " << arg); + this->Internals->LastArgument = cc; + if ( this->GetMatchedArguments(&matches, arg) ) { // Ok, we found one or more arguments that match what user specified. // Let's find the longest one. @@ -201,114 +214,87 @@ int CommandLineArguments::Parse() } // So, the longest one is probably the right one. Now see if it has any // additional value - const char* value = 0; CommandLineArgumentsCallbackStructure *cs = &this->Internals->Callbacks[matches[maxidx]]; const CommandLineArguments::Internal::String& sarg = matches[maxidx]; - if ( cs->ArgumentType == NO_ARGUMENT ) + if ( cs->Argument != sarg ) { - // No value + abort(); } - else if ( cs->ArgumentType == SPACE_ARGUMENT ) + switch ( cs->ArgumentType ) + { + case NO_ARGUMENT: + // No value + if ( !this->PopulateVariable(cs, 0) ) { + return 0; + } + break; + case SPACE_ARGUMENT: if ( cc == this->Internals->Argv.size()-1 ) { this->Internals->LastArgument --; return 0; } + CommandLineArguments_DEBUG("This is a space argument: " << arg + << " value: " << this->Internals->Argv[cc+1].c_str()); // Value is the next argument - value = this->Internals->Argv[cc+1].c_str(); - cc ++; - } - else if ( cs->ArgumentType == EQUAL_ARGUMENT ) + if ( !this->PopulateVariable(cs, this->Internals->Argv[cc+1].c_str()) ) { + return 0; + } + cc ++; + break; + case EQUAL_ARGUMENT: if ( arg.size() == sarg.size() || *(arg.c_str() + sarg.size()) != '=' ) { this->Internals->LastArgument --; return 0; } // Value is everythng followed the '=' sign - value = arg.c_str() + sarg.size()+1; - } - else if ( cs->ArgumentType == CONCAT_ARGUMENT ) + if ( !this->PopulateVariable(cs, arg.c_str() + sarg.size() + 1) ) { - // Value is whatever follows the argument - value = arg.c_str() + sarg.size(); - } - - // Call the callback - if ( cs->Callback ) - { - if ( !cs->Callback(sarg.c_str(), value, cs->CallData) ) - { - this->Internals->LastArgument --; return 0; } - } - if ( cs->Variable ) - { - kwsys_stl::string var = "1"; - if ( value ) - { - var = value; - } - if ( cs->VariableType == CommandLineArguments::INT_TYPE ) - { - int* variable = static_cast<int*>(cs->Variable); - char* res = 0; - *variable = strtol(var.c_str(), &res, 10); - //if ( res && *res ) - // { - // Can handle non-int - // } - } - else if ( cs->VariableType == CommandLineArguments::DOUBLE_TYPE ) + break; + case CONCAT_ARGUMENT: + // Value is whatever follows the argument + if ( !this->PopulateVariable(cs, arg.c_str() + sarg.size()) ) { - double* variable = static_cast<double*>(cs->Variable); - char* res = 0; - *variable = strtod(var.c_str(), &res); - //if ( res && *res ) - // { - // Can handle non-int - // } + return 0; } - else if ( cs->VariableType == CommandLineArguments::STRING_TYPE ) + break; + case MULTI_ARGUMENT: + // Suck in all the rest of the arguments + CommandLineArguments_DEBUG("This is a multi argument: " << arg); + for (cc++; cc < this->Internals->Argv.size(); ++ cc ) { - char** variable = static_cast<char**>(cs->Variable); - if ( *variable ) + const kwsys_stl::string& marg = this->Internals->Argv[cc]; + CommandLineArguments_DEBUG(" check multi argument value: " << marg); + if ( this->GetMatchedArguments(&matches, marg) ) { - delete [] *variable; - *variable = 0; - } - *variable = new char[ strlen(var.c_str()) + 1 ]; - strcpy(*variable, var.c_str()); + CommandLineArguments_DEBUG("End of multi argument " << arg << " with value: " << marg); + break; } - else if ( cs->VariableType == CommandLineArguments::STL_STRING_TYPE ) + CommandLineArguments_DEBUG(" populate multi argument value: " << marg); + if ( !this->PopulateVariable(cs, marg.c_str()) ) { - kwsys_stl::string* variable = static_cast<kwsys_stl::string*>(cs->Variable); - *variable = var; + return 0; } - else if ( cs->VariableType == CommandLineArguments::BOOL_TYPE ) - { - bool* variable = static_cast<bool*>(cs->Variable); - if ( var == "1" || var == "ON" || var == "TRUE" || var == "true" || var == "on" || - var == "True" || var == "yes" || var == "Yes" || var == "YES" ) - { - *variable = true; } - else + if ( cc != this->Internals->Argv.size() ) { - *variable = false; + CommandLineArguments_DEBUG("Again End of multi argument " << arg); + cc--; + continue; } - } - else - { - kwsys_ios::cerr << "Got unknown argument type: \"" << cs->VariableType << "\"" << kwsys_ios::endl; + break; + default: + kwsys_ios::cerr << "Got unknown argument type: \"" << cs->ArgumentType << "\"" << kwsys_ios::endl; this->Internals->LastArgument --; return 0; } } - } else { // Handle unknown arguments @@ -322,6 +308,11 @@ int CommandLineArguments::Parse() } return 1; } + else if ( this->StoreUnusedArgumentsFlag ) + { + CommandLineArguments_DEBUG("Store unused argument " << arg); + this->Internals->UnusedArguments.push_back(arg.c_str()); + } else { kwsys_ios::cerr << "Got unknown argument: \"" << arg.c_str() << "\"" << kwsys_ios::endl; @@ -359,6 +350,32 @@ void CommandLineArguments::GetRemainingArguments(int* argc, char*** argv) } //---------------------------------------------------------------------------- +void CommandLineArguments::GetUnusedArguments(int* argc, char*** argv) +{ + CommandLineArguments::Internal::VectorOfStrings::size_type size + = this->Internals->UnusedArguments.size() + 1; + CommandLineArguments::Internal::VectorOfStrings::size_type cc; + + // Copy Argv0 as the first argument + char** args = new char*[ size ]; + args[0] = new char[ this->Internals->Argv0.size() + 1 ]; + strcpy(args[0], this->Internals->Argv0.c_str()); + int cnt = 1; + + // Copy everything after the LastArgument, since that was not parsed. + for ( cc = 0; + cc < this->Internals->UnusedArguments.size(); cc ++ ) + { + kwsys::String &str = this->Internals->UnusedArguments[cc]; + args[cnt] = new char[ str.size() + 1]; + strcpy(args[cnt], str.c_str()); + cnt ++; + } + *argc = cnt; + *argv = args; +} + +//---------------------------------------------------------------------------- void CommandLineArguments::DeleteRemainingArguments(int argc, char*** argv) { int cc; @@ -404,55 +421,39 @@ void CommandLineArguments::AddArgument(const char* argument, ArgumentTypeEnum ty } //---------------------------------------------------------------------------- -void CommandLineArguments::AddArgument(const char* argument, ArgumentTypeEnum type, - int* variable, const char* help) -{ - this->AddArgument(argument, type, CommandLineArguments::INT_TYPE, variable, help); -} - -//---------------------------------------------------------------------------- -void CommandLineArguments::AddArgument(const char* argument, ArgumentTypeEnum type, - double* variable, const char* help) -{ - this->AddArgument(argument, type, CommandLineArguments::DOUBLE_TYPE, variable, help); -} +#define CommandLineArgumentsAddArgumentMacro(type, ctype) \ + void CommandLineArguments::AddArgument(const char* argument, ArgumentTypeEnum type, \ + ctype* variable, const char* help) \ + { \ + this->AddArgument(argument, type, CommandLineArguments::type##_TYPE, variable, help); \ + } + +CommandLineArgumentsAddArgumentMacro(BOOL, bool); +CommandLineArgumentsAddArgumentMacro(INT, int); +CommandLineArgumentsAddArgumentMacro(DOUBLE, double); +CommandLineArgumentsAddArgumentMacro(STRING, char*); +CommandLineArgumentsAddArgumentMacro(STL_STRING, kwsys_stl::string); + +CommandLineArgumentsAddArgumentMacro(VECTOR_BOOL, kwsys_stl::vector<bool>); +CommandLineArgumentsAddArgumentMacro(VECTOR_INT, kwsys_stl::vector<int>); +CommandLineArgumentsAddArgumentMacro(VECTOR_DOUBLE, kwsys_stl::vector<double>); +CommandLineArgumentsAddArgumentMacro(VECTOR_STRING, kwsys_stl::vector<char*>); +CommandLineArgumentsAddArgumentMacro(VECTOR_STL_STRING, kwsys_stl::vector<kwsys_stl::string>); //---------------------------------------------------------------------------- -void CommandLineArguments::AddArgument(const char* argument, ArgumentTypeEnum type, - char** variable, const char* help) -{ - this->AddArgument(argument, type, CommandLineArguments::STRING_TYPE, variable, help); -} - -//---------------------------------------------------------------------------- -void CommandLineArguments::AddArgument(const char* argument, ArgumentTypeEnum type, - kwsys_stl::string* variable, const char* help) -{ - this->AddArgument(argument, type, CommandLineArguments::STL_STRING_TYPE, variable, help); -} - -//---------------------------------------------------------------------------- -void CommandLineArguments::AddArgument(const char* argument, ArgumentTypeEnum type, - bool* variable, const char* help) -{ - this->AddArgument(argument, type, CommandLineArguments::BOOL_TYPE, variable, help); -} - -//---------------------------------------------------------------------------- -void CommandLineArguments::AddBooleanArgument(const char* argument, bool* - variable, const char* help) -{ - this->AddArgument(argument, CommandLineArguments::NO_ARGUMENT, - CommandLineArguments::BOOL_TYPE, variable, help); -} - -//---------------------------------------------------------------------------- -void CommandLineArguments::AddBooleanArgument(const char* argument, int* - variable, const char* help) -{ - this->AddArgument(argument, CommandLineArguments::NO_ARGUMENT, - CommandLineArguments::INT_TYPE, variable, help); -} +#define CommandLineArgumentsAddBooleanArgumentMacro(type, ctype) \ + void CommandLineArguments::AddBooleanArgument(const char* argument, \ + ctype* variable, const char* help) \ + { \ + this->AddArgument(argument, CommandLineArguments::NO_ARGUMENT, \ + CommandLineArguments::type##_TYPE, variable, help); \ + } + +CommandLineArgumentsAddBooleanArgumentMacro(BOOL, bool); +CommandLineArgumentsAddBooleanArgumentMacro(INT, int); +CommandLineArgumentsAddBooleanArgumentMacro(DOUBLE, double); +CommandLineArgumentsAddBooleanArgumentMacro(STRING, char*); +CommandLineArgumentsAddBooleanArgumentMacro(STL_STRING, kwsys_stl::string); //---------------------------------------------------------------------------- void CommandLineArguments::SetClientData(void* client_data) @@ -513,7 +514,7 @@ const char* CommandLineArguments::GetArgv0() //---------------------------------------------------------------------------- unsigned int CommandLineArguments::GetLastArgument() { - return (unsigned int)this->Internals->LastArgument + 1; + return static_cast<unsigned int>(this->Internals->LastArgument + 1); } //---------------------------------------------------------------------------- @@ -614,6 +615,7 @@ void CommandLineArguments::GenerateHelp() case CommandLineArguments::CONCAT_ARGUMENT: strcat(argument, "opt"); break; case CommandLineArguments::SPACE_ARGUMENT: strcat(argument, " opt"); break; case CommandLineArguments::EQUAL_ARGUMENT: strcat(argument, "=opt"); break; + case CommandLineArguments::MULTI_ARGUMENT: strcat(argument, " opt opt ..."); break; } char buffer[80]; sprintf(buffer, format, argument); @@ -678,4 +680,182 @@ void CommandLineArguments::GenerateHelp() this->Help = str.str(); } +//---------------------------------------------------------------------------- +void CommandLineArguments::PopulateVariable( + bool* variable, const kwsys_stl::string& value) +{ + if ( value == "1" || value == "ON" || value == "on" || value == "On" || + value == "TRUE" || value == "true" || value == "True" || + value == "yes" || value == "Yes" || value == "YES" ) + { + *variable = true; + } + else + { + *variable = false; + } +} + +//---------------------------------------------------------------------------- +void CommandLineArguments::PopulateVariable( + int* variable, const kwsys_stl::string& value) +{ + char* res = 0; + *variable = strtol(value.c_str(), &res, 10); + //if ( res && *res ) + // { + // Can handle non-int + // } +} + +//---------------------------------------------------------------------------- +void CommandLineArguments::PopulateVariable( + double* variable, const kwsys_stl::string& value) +{ + char* res = 0; + *variable = strtod(value.c_str(), &res); + //if ( res && *res ) + // { + // Can handle non-double + // } +} + +//---------------------------------------------------------------------------- +void CommandLineArguments::PopulateVariable( + char** variable, const kwsys_stl::string& value) +{ + if ( *variable ) + { + delete [] *variable; + *variable = 0; + } + *variable = new char[ value.size() + 1 ]; + strcpy(*variable, value.c_str()); +} + +//---------------------------------------------------------------------------- +void CommandLineArguments::PopulateVariable( + kwsys_stl::string* variable, const kwsys_stl::string& value) +{ + *variable = value; +} + +//---------------------------------------------------------------------------- +void CommandLineArguments::PopulateVariable( + kwsys_stl::vector<bool>* variable, const kwsys_stl::string& value) +{ + bool val = false; + if ( value == "1" || value == "ON" || value == "on" || value == "On" || + value == "TRUE" || value == "true" || value == "True" || + value == "yes" || value == "Yes" || value == "YES" ) + { + val = true; + } + variable->push_back(val); +} + +//---------------------------------------------------------------------------- +void CommandLineArguments::PopulateVariable( + kwsys_stl::vector<int>* variable, const kwsys_stl::string& value) +{ + char* res = 0; + variable->push_back(strtol(value.c_str(), &res, 10)); + //if ( res && *res ) + // { + // Can handle non-int + // } +} + +//---------------------------------------------------------------------------- +void CommandLineArguments::PopulateVariable( + kwsys_stl::vector<double>* variable, const kwsys_stl::string& value) +{ + char* res = 0; + variable->push_back(strtod(value.c_str(), &res)); + //if ( res && *res ) + // { + // Can handle non-int + // } +} + +//---------------------------------------------------------------------------- +void CommandLineArguments::PopulateVariable( + kwsys_stl::vector<char*>* variable, const kwsys_stl::string& value) +{ + char* var = new char[ value.size() + 1 ]; + strcpy(var, value.c_str()); + variable->push_back(var); +} + +//---------------------------------------------------------------------------- +void CommandLineArguments::PopulateVariable( + kwsys_stl::vector<kwsys_stl::string>* variable, + const kwsys_stl::string& value) +{ + variable->push_back(value); +} + +//---------------------------------------------------------------------------- +bool CommandLineArguments::PopulateVariable(CommandLineArgumentsCallbackStructure* cs, + const char* value) +{ + // Call the callback + if ( cs->Callback ) + { + if ( !cs->Callback(cs->Argument, value, cs->CallData) ) + { + this->Internals->LastArgument --; + return 0; + } + } + CommandLineArguments_DEBUG("Set argument: " << cs->Argument << " to " << value); + if ( cs->Variable ) + { + kwsys_stl::string var = "1"; + if ( value ) + { + var = value; + } + switch ( cs->VariableType ) + { + case CommandLineArguments::INT_TYPE: + this->PopulateVariable(static_cast<int*>(cs->Variable), var); + break; + case CommandLineArguments::DOUBLE_TYPE: + this->PopulateVariable(static_cast<double*>(cs->Variable), var); + break; + case CommandLineArguments::STRING_TYPE: + this->PopulateVariable(static_cast<char**>(cs->Variable), var); + break; + case CommandLineArguments::STL_STRING_TYPE: + this->PopulateVariable(static_cast<kwsys_stl::string*>(cs->Variable), var); + break; + case CommandLineArguments::BOOL_TYPE: + this->PopulateVariable(static_cast<bool*>(cs->Variable), var); + break; + case CommandLineArguments::VECTOR_BOOL_TYPE: + this->PopulateVariable(static_cast<kwsys_stl::vector<bool>*>(cs->Variable), var); + break; + case CommandLineArguments::VECTOR_INT_TYPE: + this->PopulateVariable(static_cast<kwsys_stl::vector<int>*>(cs->Variable), var); + break; + case CommandLineArguments::VECTOR_DOUBLE_TYPE: + this->PopulateVariable(static_cast<kwsys_stl::vector<double>*>(cs->Variable), var); + break; + case CommandLineArguments::VECTOR_STRING_TYPE: + this->PopulateVariable(static_cast<kwsys_stl::vector<char*>*>(cs->Variable), var); + break; + case CommandLineArguments::VECTOR_STL_STRING_TYPE: + this->PopulateVariable(static_cast<kwsys_stl::vector<kwsys_stl::string>*>(cs->Variable), var); + break; + default: + kwsys_ios::cerr << "Got unknown variable type: \"" << cs->VariableType << "\"" << kwsys_ios::endl; + this->Internals->LastArgument --; + return 0; + } + } + return 1; +} + + } // namespace KWSYS_NAMESPACE diff --git a/Source/kwsys/CommandLineArguments.hxx.in b/Source/kwsys/CommandLineArguments.hxx.in index eea51eb04f..6fe7f9996f 100644 --- a/Source/kwsys/CommandLineArguments.hxx.in +++ b/Source/kwsys/CommandLineArguments.hxx.in @@ -18,6 +18,7 @@ #include <@KWSYS_NAMESPACE@/Configure.hxx> #include <@KWSYS_NAMESPACE@/stl/string> +#include <@KWSYS_NAMESPACE@/stl/vector> /* Define this macro temporarily to keep the code readable. */ #if !defined (KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE@_NAME_IS_KWSYS @@ -28,6 +29,7 @@ namespace @KWSYS_NAMESPACE@ { class CommandLineArgumentsInternal; +struct CommandLineArgumentsCallbackStructure; /** \class CommandLineArguments * \brief Command line arguments processing code. @@ -53,6 +55,7 @@ class CommandLineArgumentsInternal; * CONCAT_ARGUMENT - The argument takes value after no space : --Aval * SPACE_ARGUMENT - The argument takes value after space : --A val * EQUAL_ARGUMENT - The argument takes value after equal : --A=val + * MULTI_ARGUMENT - The argument takes values after space : --A val1 val2 val3 ... * * Example use: * @@ -82,7 +85,8 @@ public: NO_ARGUMENT, CONCAT_ARGUMENT, SPACE_ARGUMENT, - EQUAL_ARGUMENT + EQUAL_ARGUMENT, + MULTI_ARGUMENT }; /** @@ -95,7 +99,13 @@ public: BOOL_TYPE, // The vairable is boolean (bool) DOUBLE_TYPE, // The variable is float (double) STRING_TYPE, // The variable is string (char*) - STL_STRING_TYPE // The variable is string (char*) + STL_STRING_TYPE, // The variable is string (char*) + VECTOR_INT_TYPE, // The variable is integer (int) + VECTOR_BOOL_TYPE, // The vairable is boolean (bool) + VECTOR_DOUBLE_TYPE, // The variable is float (double) + VECTOR_STRING_TYPE, // The variable is string (char*) + VECTOR_STL_STRING_TYPE, // The variable is string (char*) + LAST_VARIABLE_TYPE }; /** @@ -138,10 +148,10 @@ public: * specified value. If the argument is specified, the option is casted to the * apropriate type. */ - void AddArgument(const char* argument, ArgumentTypeEnum type, bool* variable, - const char* help); - void AddArgument(const char* argument, ArgumentTypeEnum type, int* variable, - const char* help); + void AddArgument(const char* argument, ArgumentTypeEnum type, + bool* variable, const char* help); + void AddArgument(const char* argument, ArgumentTypeEnum type, + int* variable, const char* help); void AddArgument(const char* argument, ArgumentTypeEnum type, double* variable, const char* help); void AddArgument(const char* argument, ArgumentTypeEnum type, @@ -150,14 +160,36 @@ public: kwsys_stl::string* variable, const char* help); /** + * Add handler for argument which is going to set the variable to the + * specified value. If the argument is specified, the option is casted to the + * apropriate type. This will handle the multi argument values. + */ + void AddArgument(const char* argument, ArgumentTypeEnum type, + kwsys_stl::vector<bool>* variable, const char* help); + void AddArgument(const char* argument, ArgumentTypeEnum type, + kwsys_stl::vector<int>* variable, const char* help); + void AddArgument(const char* argument, ArgumentTypeEnum type, + kwsys_stl::vector<double>* variable, const char* help); + void AddArgument(const char* argument, ArgumentTypeEnum type, + kwsys_stl::vector<char*>* variable, const char* help); + void AddArgument(const char* argument, ArgumentTypeEnum type, + kwsys_stl::vector<kwsys_stl::string>* variable, const char* help); + + /** * Add handler for boolean argument. The argument does not take any option * and if it is specified, the value of the variable is true/1, otherwise it * is false/0. */ - void AddBooleanArgument(const char* argument, bool* variable, const char* - help); - void AddBooleanArgument(const char* argument, int* variable, const char* - help); + void AddBooleanArgument(const char* argument, + bool* variable, const char* help); + void AddBooleanArgument(const char* argument, + int* variable, const char* help); + void AddBooleanArgument(const char* argument, + double* variable, const char* help); + void AddBooleanArgument(const char* argument, + char** variable, const char* help); + void AddBooleanArgument(const char* argument, + kwsys_stl::string* variable, const char* help); /** * Set the callbacks for error handling. @@ -173,6 +205,14 @@ public: void DeleteRemainingArguments(int argc, char*** argv); /** + * If StoreUnusedArguments is set to true, then all unknown arguments will be + * stored and the user can access the modified argc, argv without known + * arguments. + */ + void StoreUnusedArguments(bool val) { this->StoreUnusedArgumentsFlag = val; } + void GetUnusedArguments(int* argc, char*** argv); + + /** * Return string containing help. If the argument is specified, only return * help for that argument. */ @@ -205,11 +245,32 @@ protected: void AddArgument(const char* argument, ArgumentTypeEnum type, VariableTypeEnum vtype, void* variable, const char* help); + bool GetMatchedArguments(kwsys_stl::vector<kwsys_stl::string>* matches, + const kwsys_stl::string& arg); + + //! Populate individual variables + bool PopulateVariable(CommandLineArgumentsCallbackStructure* cs, + const char* value); + + //! Populate individual variables of type ... + void PopulateVariable(bool* variable, const kwsys_stl::string& value); + void PopulateVariable(int* variable, const kwsys_stl::string& value); + void PopulateVariable(double* variable, const kwsys_stl::string& value); + void PopulateVariable(char** variable, const kwsys_stl::string& value); + void PopulateVariable(kwsys_stl::string* variable, const kwsys_stl::string& value); + void PopulateVariable(kwsys_stl::vector<bool>* variable, const kwsys_stl::string& value); + void PopulateVariable(kwsys_stl::vector<int>* variable, const kwsys_stl::string& value); + void PopulateVariable(kwsys_stl::vector<double>* variable, const kwsys_stl::string& value); + void PopulateVariable(kwsys_stl::vector<char*>* variable, const kwsys_stl::string& value); + void PopulateVariable(kwsys_stl::vector<kwsys_stl::string>* variable, const kwsys_stl::string& value); + typedef CommandLineArgumentsInternal Internal; Internal* Internals; kwsys_stl::string Help; unsigned int LineLength; + + bool StoreUnusedArgumentsFlag; }; } // namespace @KWSYS_NAMESPACE@ diff --git a/Source/kwsys/Glob.cxx b/Source/kwsys/Glob.cxx index f39512645e..15f0e71947 100644 --- a/Source/kwsys/Glob.cxx +++ b/Source/kwsys/Glob.cxx @@ -338,7 +338,7 @@ bool Glob::FindFiles(const kwsys_stl::string& inexpr) { if ( cc > 0 && expr[cc] == '/' && expr[cc-1] != '\\' ) { - last_slash = (int)cc; + last_slash = static_cast<int>(cc); } if ( cc > 0 && (expr[cc] == '[' || expr[cc] == '?' || expr[cc] == '*') && diff --git a/Source/kwsys/ProcessWin32.c b/Source/kwsys/ProcessWin32.c index 6929c3e443..6b943dc993 100644 --- a/Source/kwsys/ProcessWin32.c +++ b/Source/kwsys/ProcessWin32.c @@ -1593,8 +1593,9 @@ int kwsysProcessCreate(kwsysProcess* cp, int index, else if(cp->PipeFileSTDIN) { /* Create a handle to read a file for stdin. */ - HANDLE fin = CreateFile(cp->PipeFileSTDIN, GENERIC_READ, - FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0); + HANDLE fin = CreateFile(cp->PipeFileSTDIN, GENERIC_READ|GENERIC_WRITE, + FILE_SHARE_READ|FILE_SHARE_WRITE, + 0, OPEN_EXISTING, 0, 0); if(fin == INVALID_HANDLE_VALUE) { return 0; diff --git a/Source/kwsys/Registry.cxx b/Source/kwsys/Registry.cxx index b09898adef..a4e8d027d7 100644 --- a/Source/kwsys/Registry.cxx +++ b/Source/kwsys/Registry.cxx @@ -211,7 +211,7 @@ bool Registry::ReadValue(const char *subkey, const char **value) { *value = 0; - bool res = true; + bool res = false; bool open = false; if ( ! value ) { @@ -241,7 +241,7 @@ bool Registry::ReadValue(const char *subkey, //---------------------------------------------------------------------------- bool Registry::DeleteKey(const char *subkey, const char *key) { - bool res = true; + bool res = false; bool open = false; if ( !m_Opened ) { @@ -272,7 +272,7 @@ bool Registry::DeleteKey(const char *subkey, const char *key) //---------------------------------------------------------------------------- bool Registry::DeleteValue(const char *subkey, const char *key) { - bool res = true; + bool res = false; bool open = false; if ( !m_Opened ) { @@ -713,7 +713,7 @@ char *RegistryHelper::Strip(char *str) } len = strlen(str); nstr = str; - for( cc=0; cc<(int)len; cc++ ) + for( cc=0; cc < static_cast<int>(len); cc++ ) { if ( !isspace( *nstr ) ) { @@ -721,7 +721,7 @@ char *RegistryHelper::Strip(char *str) } nstr ++; } - for( cc=int(strlen(nstr)-1); cc>=0; cc-- ) + for( cc= static_cast<int>(strlen(nstr))-1; cc>=0; cc-- ) { if ( !isspace( nstr[cc] ) ) { diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx index 4c9bbb4b51..d16d4d3c1b 100644 --- a/Source/kwsys/SystemTools.cxx +++ b/Source/kwsys/SystemTools.cxx @@ -237,10 +237,10 @@ SystemTools::GetTime(void) struct timeval t; #ifdef GETTIMEOFDAY_NO_TZ if (gettimeofday(&t) == 0) - return (double)t.tv_sec + t.tv_usec*0.000001; + return static_cast<double>(t.tv_sec) + t.tv_usec*0.000001; #else /* !GETTIMEOFDAY_NO_TZ */ - if (gettimeofday(&t, (struct timezone *)NULL) == 0) - return (double)t.tv_sec + t.tv_usec*0.000001; + if (gettimeofday(&t, static_cast<struct timezone *>(NULL)) == 0) + return static_cast<double>(t.tv_sec) + t.tv_usec*0.000001; #endif /* !GETTIMEOFDAY_NO_TZ */ } #endif /* !HAVE_GETTIMEOFDAY */ @@ -248,11 +248,12 @@ SystemTools::GetTime(void) #if defined(HAVE_FTIME) struct TIMEB t; ::FTIME(&t); - return (double)t.time + (double)t.millitm * (double)0.001; + return static_cast<double>(t.time) + + static_cast<double>(t.millitm) * static_cast<double>(0.001); #else /* !HAVE_FTIME */ time_t secs; time(&secs); - return (double)secs; + return static_cast<double>(secs); #endif /* !HAVE_FTIME */ } } @@ -1246,7 +1247,7 @@ int SystemTools::EstimateFormatLength(const char *format, va_list ap) } } - return (int)length; + return static_cast<int>(length); } kwsys_stl::string SystemTools::EscapeChars( @@ -1506,7 +1507,8 @@ bool SystemTools::FilesDiffer(const char* source, } // If this block differs the file differs. - if(memcmp((const void*)source_buf, (const void*)dest_buf, nnext) != 0) + if(memcmp(static_cast<const void*>(source_buf), + static_cast<const void*>(dest_buf), nnext) != 0) { return true; } @@ -1736,7 +1738,7 @@ long int SystemTools::ModifiedTime(const char* filename) } else { - return (long int)fs.st_mtime; + return static_cast<long int>(fs.st_mtime); } } @@ -1750,7 +1752,7 @@ long int SystemTools::CreationTime(const char* filename) } else { - return fs.st_ctime >= 0 ? (long int)fs.st_ctime : 0; + return fs.st_ctime >= 0 ? static_cast<long int>(fs.st_ctime) : 0; } } @@ -2237,7 +2239,7 @@ bool SystemTools::FileIsDirectory(const char* name) struct stat fs; if(stat(name, &fs) == 0) { -#if _WIN32 +#if defined( _WIN32 ) return ((fs.st_mode & _S_IFDIR) != 0); #else return S_ISDIR(fs.st_mode); @@ -2251,7 +2253,7 @@ bool SystemTools::FileIsDirectory(const char* name) bool SystemTools::FileIsSymlink(const char* name) { -#if _WIN32 +#if defined( _WIN32 ) (void)name; return false; #else @@ -3076,7 +3078,8 @@ SystemTools::DetectFileType(const char *filename, delete [] buffer; double current_percent_bin = - ((double)(read_length - text_count) / (double)read_length); + (static_cast<double>(read_length - text_count) / + static_cast<double>(read_length)); if (current_percent_bin >= percent_bin) { @@ -3106,14 +3109,14 @@ bool SystemTools::LocateFileInDir(const char *filename, kwsys_stl::string real_dir; if (!SystemTools::FileIsDirectory(dir)) { -#if _WIN32 +#if defined( _WIN32 ) size_t dir_len = strlen(dir); if (dir_len < 2 || dir[dir_len - 1] != ':') { #endif real_dir = SystemTools::GetFilenamePath(dir); dir = real_dir.c_str(); -#if _WIN32 +#if defined( _WIN32 ) } #endif } @@ -3154,7 +3157,7 @@ bool SystemTools::LocateFileInDir(const char *filename, { filename_dir = SystemTools::GetFilenamePath(filename_dir); filename_dir_base = SystemTools::GetFilenameName(filename_dir); -#if _WIN32 +#if defined( _WIN32 ) if (!filename_dir_base.size() || filename_dir_base[filename_dir_base.size() - 1] == ':') #else @@ -3416,7 +3419,7 @@ int SystemTools::GetTerminalWidth() t = strtol(columns, &endptr, 0); if(endptr && !*endptr && (t>0) && (t<1000)) { - width = (int)t; + width = static_cast<int>(t); } } if ( width < 9 ) diff --git a/Source/kwsys/Terminal.c b/Source/kwsys/Terminal.c index e3265a1280..59b223591f 100644 --- a/Source/kwsys/Terminal.c +++ b/Source/kwsys/Terminal.c @@ -160,6 +160,15 @@ static const char* kwsysTerminalVT100Names[] = static int kwsysTerminalStreamIsVT100(FILE* stream, int default_vt100, int default_tty) { + /* If running inside emacs the terminal is not VT100. Some emacs + seem to claim the TERM is xterm even though they do not support + VT100 escapes. */ + const char* emacs = getenv("EMACS"); + if(emacs && *emacs == 't') + { + return 0; + } + /* Check for a valid terminal. */ if(!default_vt100) { diff --git a/Source/kwsys/kwsys_ios_iostream.h.in b/Source/kwsys/kwsys_ios_iostream.h.in index c00596f8f0..2cc4b06780 100644 --- a/Source/kwsys/kwsys_ios_iostream.h.in +++ b/Source/kwsys/kwsys_ios_iostream.h.in @@ -28,17 +28,67 @@ # include <iostream.h> #endif +// The HP implementation of iostream defines cin, cout, cerr, and clog +// as macros in order to do thread-private streams. +// See /opt/aCC/include/iostream/iostream.h for details. +// This block redefines the macros in a safe way that is also compatible +// with the HP definitions and the using declarations below. + +#if !@KWSYS_NAMESPACE@_IOS_USE_SSTREAM +# if defined(__HP_aCC) && (defined(HP_THREAD_SAFE) || defined(_THREAD_SAFE)) +# if defined(cin) && !defined(@KWSYS_NAMESPACE@_IOS_HP_HACK_CIN) +# define @KWSYS_NAMESPACE@_IOS_HP_HACK_CIN +# undef cin +# define cin __tcin.ref() +# endif +# if defined(cout) && !defined(@KWSYS_NAMESPACE@_IOS_HP_HACK_COUT) +# define @KWSYS_NAMESPACE@_IOS_HP_HACK_COUT +# undef cout +# define cout __tcout.ref() +# endif +# if defined(cerr) && !defined(@KWSYS_NAMESPACE@_IOS_HP_HACK_CERR) +# define @KWSYS_NAMESPACE@_IOS_HP_HACK_CERR +# undef cerr +# define cerr __tcerr.ref() +# endif +# if defined(clog) && !defined(@KWSYS_NAMESPACE@_IOS_HP_HACK_CLOG) +# define @KWSYS_NAMESPACE@_IOS_HP_HACK_CLOG +# undef clog +# define clog __tclog.ref() +# endif +# endif +#endif + +// If using our own sstream emulation code, put the standard +// streams in the same namespace. #if !@KWSYS_NAMESPACE@_IOS_USE_SSTREAM namespace @KWSYS_NAMESPACE@_ios { using @KWSYS_NAMESPACE@_ios_namespace::ostream; using @KWSYS_NAMESPACE@_ios_namespace::istream; using @KWSYS_NAMESPACE@_ios_namespace::ios; - using @KWSYS_NAMESPACE@_ios_namespace::cout; - using @KWSYS_NAMESPACE@_ios_namespace::cerr; - using @KWSYS_NAMESPACE@_ios_namespace::cin; using @KWSYS_NAMESPACE@_ios_namespace::endl; using @KWSYS_NAMESPACE@_ios_namespace::flush; +# if defined(@KWSYS_NAMESPACE@_IOS_HP_HACK_CIN) + using @KWSYS_NAMESPACE@_ios_namespace::__tcin; +# else + using @KWSYS_NAMESPACE@_ios_namespace::cin; +# endif +# if defined(@KWSYS_NAMESPACE@_IOS_HP_HACK_COUT) + using @KWSYS_NAMESPACE@_ios_namespace::__tcout; +# else + using @KWSYS_NAMESPACE@_ios_namespace::cout; +# endif +# if defined(@KWSYS_NAMESPACE@_IOS_HP_HACK_CERR) + using @KWSYS_NAMESPACE@_ios_namespace::__tcerr; +# else + using @KWSYS_NAMESPACE@_ios_namespace::cerr; +# endif +# if defined(@KWSYS_NAMESPACE@_IOS_HP_HACK_CLOG) + using @KWSYS_NAMESPACE@_ios_namespace::__tclog; +# else + using @KWSYS_NAMESPACE@_ios_namespace::clog; +# endif } #endif diff --git a/Source/kwsys/testCommandLineArguments.cxx b/Source/kwsys/testCommandLineArguments.cxx index 73207c9cbc..03d63a8403 100644 --- a/Source/kwsys/testCommandLineArguments.cxx +++ b/Source/kwsys/testCommandLineArguments.cxx @@ -14,6 +14,7 @@ #include "kwsysPrivate.h" #include KWSYS_HEADER(CommandLineArguments.hxx) #include KWSYS_HEADER(ios/iostream) +#include KWSYS_HEADER(stl/vector) // Work-around CMake dependency scanning limitation. This must // duplicate the above list of headers. @@ -46,6 +47,14 @@ int unknown_argument(const char* argument, void* call_data) return 1; } +bool CompareTwoItemsOnList(bool i1, bool i2) { return i1 == i2; } +bool CompareTwoItemsOnList(int i1, int i2) { return i1 == i2; } +bool CompareTwoItemsOnList(double i1, double i2) { return i1 == i2; } +bool CompareTwoItemsOnList(const char* i1, + const char* i2) { return strcmp(i1, i2) == 0; } +bool CompareTwoItemsOnList(const kwsys_stl::string& i1, + const kwsys_stl::string& i2) { return i1 == i2; } + int main(int argc, char* argv[]) { // Example run: ./testCommandLineArguments --some-int-variable 4 @@ -70,6 +79,21 @@ int main(int argc, char* argv[]) bool bool_arg1 = false; int bool_arg2 = 0; + kwsys_stl::vector<int> numbers_argument; + int valid_numbers[] = { 5, 1, 8, 3, 7, 1, 3, 9, 7, 1 }; + + kwsys_stl::vector<double> doubles_argument; + double valid_doubles[] = { 12.5, 1.31, 22 }; + + kwsys_stl::vector<bool> bools_argument; + bool valid_bools[] = { true, true, false }; + + kwsys_stl::vector<char*> strings_argument; + const char* valid_strings[] = { "andy", "bill", "brad", "ken" }; + + kwsys_stl::vector<kwsys_stl::string> stl_strings_argument; + kwsys_stl::string valid_stl_strings[] = { "ken", "brad", "bill", "andy" }; + typedef kwsys::CommandLineArguments argT; arg.AddArgument("--some-int-variable", argT::SPACE_ARGUMENT, &some_int_variable, "Set some random int variable"); @@ -80,6 +104,11 @@ int main(int argc, char* argv[]) arg.AddArgument("--another-bool-variable", argT::NO_ARGUMENT, &some_bool_variable1, "Set some random bool variable 1"); arg.AddBooleanArgument("--set-bool-arg1", &bool_arg1, "Test AddBooleanArgument 1"); arg.AddBooleanArgument("--set-bool-arg2", &bool_arg2, "Test AddBooleanArgument 2"); + arg.AddArgument("--some-multi-argument", argT::MULTI_ARGUMENT, &numbers_argument, "Some multiple values variable"); + arg.AddArgument("-N", argT::SPACE_ARGUMENT, &doubles_argument, "Some explicit multiple values variable"); + arg.AddArgument("-BB", argT::CONCAT_ARGUMENT, &bools_argument, "Some explicit multiple values variable"); + arg.AddArgument("-SS", argT::EQUAL_ARGUMENT, &strings_argument, "Some explicit multiple values variable"); + arg.AddArgument("-SSS", argT::MULTI_ARGUMENT, &stl_strings_argument, "Some explicit multiple values variable"); arg.AddCallback("-A", argT::NO_ARGUMENT, argument, random_ptr, "Some option -A. This option has a multiline comment. It should demonstrate how the code splits lines."); arg.AddCallback("-B", argT::SPACE_ARGUMENT, argument, random_ptr, "Option -B takes argument with space"); @@ -99,7 +128,7 @@ int main(int argc, char* argv[]) kwsys_ios::cout << "Some int variable was set to: " << some_int_variable << kwsys_ios::endl; kwsys_ios::cout << "Some double variable was set to: " << some_double_variable << kwsys_ios::endl; - if ( some_string_variable ) + if ( some_string_variable && strcmp(some_string_variable, "test string with space") == 0) { kwsys_ios::cout << "Some string variable was set to: " << some_string_variable << kwsys_ios::endl; delete [] some_string_variable; @@ -109,11 +138,49 @@ int main(int argc, char* argv[]) kwsys_ios::cerr << "Problem setting string variable" << kwsys_ios::endl; res = 1; } + size_t cc; +#define CompareTwoLists(list1, list_valid, lsize) \ + if ( list1.size() != lsize ) \ + { \ + kwsys_ios::cerr << "Problem setting " #list1 ". Size is: " << list1.size() \ + << " should be: " << lsize << kwsys_ios::endl; \ + res = 1; \ + } \ + else \ + { \ + kwsys_ios::cout << #list1 " argument set:"; \ + for ( cc =0; cc < lsize; ++ cc ) \ + { \ + kwsys_ios::cout << " " << list1[cc]; \ + if ( !CompareTwoItemsOnList(list1[cc], list_valid[cc]) ) \ + { \ + kwsys_ios::cerr << "Problem setting " #list1 ". Value of " \ + << cc << " is: [" << list1[cc] << "] <> [" \ + << list_valid[cc] << "]" << kwsys_ios::endl; \ + res = 1; \ + break; \ + } \ + } \ + kwsys_ios::cout << kwsys_ios::endl; \ + } + + CompareTwoLists(numbers_argument, valid_numbers, 10); + CompareTwoLists(doubles_argument, valid_doubles, 3); + CompareTwoLists(bools_argument, valid_bools, 3); + CompareTwoLists(strings_argument, valid_strings, 4); + CompareTwoLists(stl_strings_argument, valid_stl_strings, 4); + kwsys_ios::cout << "Some STL String variable was set to: " << some_stl_string_variable.c_str() << kwsys_ios::endl; kwsys_ios::cout << "Some bool variable was set to: " << some_bool_variable << kwsys_ios::endl; kwsys_ios::cout << "Some bool variable was set to: " << some_bool_variable1 << kwsys_ios::endl; kwsys_ios::cout << "bool_arg1 variable was set to: " << bool_arg1 << kwsys_ios::endl; kwsys_ios::cout << "bool_arg2 variable was set to: " << bool_arg2 << kwsys_ios::endl; kwsys_ios::cout << kwsys_ios::endl; + + for ( cc = 0; cc < strings_argument.size(); ++ cc ) + { + delete [] strings_argument[cc]; + strings_argument[cc] = 0; + } return res; } diff --git a/Source/kwsys/testCommandLineArguments1.cxx b/Source/kwsys/testCommandLineArguments1.cxx new file mode 100644 index 0000000000..dedfe3101e --- /dev/null +++ b/Source/kwsys/testCommandLineArguments1.cxx @@ -0,0 +1,106 @@ +/*========================================================================= + + Program: KWSys - Kitware System Library + Module: $RCSfile$ + + Copyright (c) Kitware, Inc., Insight Consortium. All rights reserved. + See Copyright.txt or http://www.kitware.com/Copyright.htm for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ +#include "kwsysPrivate.h" +#include KWSYS_HEADER(CommandLineArguments.hxx) +#include KWSYS_HEADER(ios/iostream) +#include KWSYS_HEADER(stl/vector) + +// Work-around CMake dependency scanning limitation. This must +// duplicate the above list of headers. +#if 0 +# include "CommandLineArguments.hxx.in" +# include "kwsys_ios_iostream.h.in" +#endif + +int main(int argc, char* argv[]) +{ + kwsys::CommandLineArguments arg; + arg.Initialize(argc, argv); + + int n = 0; + char* m = 0; + kwsys_stl::string p; + int res = 0; + + typedef kwsys::CommandLineArguments argT; + arg.AddArgument("-n", argT::SPACE_ARGUMENT, &n, "Argument N"); + arg.AddArgument("-m", argT::EQUAL_ARGUMENT, &m, "Argument M"); + arg.AddBooleanArgument("-p", &p, "Argument P"); + + arg.StoreUnusedArguments(true); + + if ( !arg.Parse() ) + { + kwsys_ios::cerr << "Problem parsing arguments" << kwsys_ios::endl; + res = 1; + } + if ( n != 24 ) + { + kwsys_ios::cout << "Problem setting N. Value of N: " << n << kwsys_ios::endl; + res = 1; + } + if ( !m || strcmp(m, "test value") != 0 ) + { + kwsys_ios::cout << "Problem setting M. Value of M: " << m << kwsys_ios::endl; + res = 1; + } + if ( p != "1" ) + { + kwsys_ios::cout << "Problem setting P. Value of P: " << p.c_str() << kwsys_ios::endl; + res = 1; + } + kwsys_ios::cout << "Value of N: " << n << kwsys_ios::endl; + kwsys_ios::cout << "Value of M: " << m << kwsys_ios::endl; + kwsys_ios::cout << "Value of P: " << p.c_str() << kwsys_ios::endl; + if ( m ) + { + delete [] m; + } + + char** newArgv = 0; + int newArgc = 0; + arg.GetUnusedArguments(&newArgc, &newArgv); + int cc; + const char* valid_unused_args[9] = { + 0, "--ignored", "--second-ignored", "third-ignored", + "some", "junk", "at", "the", "end" + }; + if ( newArgc != 9 ) + { + kwsys_ios::cerr << "Bad number of unused arguments: " << newArgc << kwsys_ios::endl; + res = 1; + } + for ( cc = 0; cc < newArgc; ++ cc ) + { + kwsys_ios::cout << "Unused argument[" << cc << "] = [" << newArgv[cc] << "]" + << kwsys_ios::endl; + if ( cc >= 9 ) + { + kwsys_ios::cerr << "Too many unused arguments: " << cc << kwsys_ios::endl; + res = 1; + } + else if ( valid_unused_args[cc] && + strcmp(valid_unused_args[cc], newArgv[cc]) != 0 ) + { + kwsys_ios::cerr << "Bad unused argument [" << cc << "] \"" + << newArgv[cc] << "\" should be: \"" << valid_unused_args[cc] << "\"" + << kwsys_ios::endl; + res = 1; + } + } + arg.DeleteRemainingArguments(newArgc, &newArgv); + + return res; +} + |